مرحبا مجددا! :) في درس اليوم، سنتحدث عن فئة المصفوفات في Java. في الدرس الأخير، تعرفنا على بنية بيانات تسمى المصفوفة. لقد تعلمنا كيفية إنشائها وملئها بالبيانات. ونظرنا في كيفية تخزينها في الذاكرة. اليوم سنلقي نظرة على بعض المهام والأمثلة للعمل مع المصفوفات التي ستراها غالبًا في العمل الحقيقي. على سبيل المثال، تخيل هذا الموقف: لدينا مجموعة من 10 أرقام عشوائية.
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
مهمتنا هي فرز هذه المصفوفة بترتيب تصاعدي: من الأصغر إلى الأكبر. في النهاية، يجب أن يبدو الأمر هكذا: [-234، -2، 16، 26، 35، 43، 92، 99، 167] كيف نفعل ذلك؟ هذه المهمة ليست تافهة. لم نفعل هذا من قبل :/ هل لديك أفكار؟ حاول ان تتوقع. إليك حل واحد:
- انتقل من خلال جميع عناصر المصفوفة. قارن كل عنصر بالعنصر الذي يليه ([0] مع [1]، [1] مع [2]، [2] مع [3]، وما إلى ذلك). إذا كان العنصر الحالي أكبر من العنصر التالي، نقوم بتبديلهما، ثم ننتقل إلى العنصر التالي. إذا لم يكن الأمر كذلك، اتركهم كما هم، واستمر
- وبالتالي، بعد المرور الأول عبر العناصر، يتم ضمان وجود القيمة الأكبر (167) في الخلية الأخيرة.
- الآن سوف نستعرض جميع العناصر مرة أخرى، ولكن هذه المرة سنبدأ بالفهرس [0] إلى العنصر قبل الأخير (الرقم الأكبر موجود بالفعل في مكانه) ونجري نفس المقارنات والمقايضات. بعد هذا المرور، في الخلية قبل الأخيرة، سيكون لدينا ثاني أكبر قيمة (99).
- كرر هذه العملية عدة مرات كما لدينا عناصر المصفوفة.
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
for (int i = numbers.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
/* Compare the elements in pairs.
If they are not in the right order,
then swap them */
if (numbers[j] > numbers[j + 1]) {
int tmp = numbers[j];
numbers[j] = numbers[j + 1];
numbers[j + 1] = tmp;
}
}
}
}
}
اه ... يبدو الأمر معقدًا بعض الشيء -_- حتى لو كان المبدأ العام مفهومًا، فلا يزال يتعين علينا كتابة الكثير من التعليمات البرمجية لحل هذه المهمة البسيطة. حسنًا، ربما بالغنا في تقدير أنفسنا؟ ربما لا تزال المهمة التي قمنا بها معقدة للغاية بالنسبة لنا. دعونا نجرب شيئا أبسط. على سبيل المثال، خذ نفس مجموعة الأرقام.
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
مهمتنا هي نسخ محتوياته إلى مجموعة أخرى.
int [] numbersCopy = new int[10];
فكر في كيفية القيام بذلك باستخدام ما تعرفه بالفعل عن المصفوفات؟ على سبيل المثال، يمكنك تصفح مصفوفة الأرقام في حلقة وكتابة عناصرها بالتسلسل في NumbersCopy :
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = new int[10];
for (int i = 0; i < numbers.length; i++) {
numbersCopy[i] = numbers[i];
}
}
}
حسنًا، اه، لقد فعلنا ذلك بشكل أساسي! يبدو أننا قمنا بحل المشكلة. ومع ذلك، إذا كنت بحاجة إلى القيام بذلك كثيرًا، فسوف يحتوي الكود الخاص بك على مجموعة من الحلقات المتطابقة. في الواقع، هذه المهام (وغيرها) تم حلها منذ فترة طويلة من قبل منشئي Java. لا نحتاج إلى "إعادة اختراع العجلة" وبرمجة الحل الخاص بنا. هناك فئة ثابتة خاصة ( المصفوفات ) لمساعدتك في أداء المهام الشائعة عند العمل مع المصفوفات. تمت إضافة طرق أداء المهام الأكثر شيوعًا التي يواجهها مبرمجو Java إلى هذه الفئة. على سبيل المثال، تم حل مهمة فرز المصفوفة، التي حاولنا التعامل معها، في سطر واحد:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
}
}
يقوم الأسلوب Arrays.sort() بفرز المصفوفة. والخوارزمية الخاصة بها أكثر كفاءة من الكود الذي كتبناه. مخرجات وحدة التحكم: [-234، -2، 16، 26، 35، 43، 80، 92، 99، 167] ملاحظة: لتحويل المصفوفة إلى سلسلة، استخدمنا طريقة أخرى لفئة Arrays : Arrays.toString() . لا تتجاوز المصفوفات في Java طريقة toString() من تلقاء نفسها. لذلك، إذا كنت تكتب ببساطة
System.out.println(numbers.toString());
سيتم استدعاء toString() الخاص بفئة الكائن . بالنسبة للمصفوفة، سيكون الإخراج شيئًا من هذا القبيل: [I@4554617c لن نخوض في التفاصيل الآن حول سبب ظهور هذا الإخراج بالضبط. الشيء الرئيسي هو أنه من الواضح أنه ليس ما نحتاجه. لكن Arrays.toString() يفعل بالضبط ما نريده. بالمناسبة، يمكن أيضًا إجراء النسخ بسهولة باستخدام فئة Arrays :
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOf(numbers, numbers.length);
System.out.println(Arrays.toString(numbersCopy));
}
}
نمرر إلى طريقة Arrays.copyOf() المصفوفة الأصلية (التي نريد نسخ القيم منها) وطول المصفوفة الجديدة التي ننسخ البيانات إليها. في هذه الحالة، أشرنا إلى number.length باعتباره الطول، لأننا نريد نسخ المصفوفة بأكملها. إذا أردنا نسخ العناصر القليلة الأولى فقط، فيمكننا تحديد طول مصفوفة أصغر جديدة:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOf(numbers, 4);
System.out.println(Arrays.toString(numbersCopy));
}
}
هنا حددنا 4 كطول المصفوفة الجديدة. وبناء على ذلك، سيتم نسخ العناصر الأربعة الأولى فقط من الأرقام إلى المصفوفة الجديدة. مخرجات وحدة التحكم: [167, -2, 16, 99] بالمناسبة، تتيح لك المصفوفات أيضًا نسخ جزء من مصفوفة من المنتصف بدلاً من بداية المصفوفة:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOfRange(numbers, 2,6);
System.out.println(Arrays.toString(numbersCopy));
}
}
الإخراج: [16، 99، 26، 92] تم نسخ الأرقام في المصفوفة الجديدة من المصفوفة الثانية من العنصر الثاني (الشامل) إلى العنصر السادس (غير الشامل). قد نحتاج أيضًا إلى مقارنة صفيفين. كما هو الحال مع طريقة toString() ، فإن المصفوفات نفسها لا تتجاوز طريقة يساوي() . لذلك إذا حاولنا مقارنتها بهذه الطريقة
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
int[] numbers2 = {1, 2, 3};
System.out.println(numbers.equals(numbers2));
}
}
ثم نحصل على كاذبة. وذلك لأنه سيتم استدعاء التابع Object.equals() ، الذي يقارن المراجع. ومن الواضح أنهم مختلفون! لكن ما نحتاجه هو مقارنة محتويات المصفوفة، وليس المراجع. تتجاوز فئة Arrays طريقة يساوي () لجعلها تفعل ما نريده بالضبط:
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
int[] numbers2 = {1, 2, 3};
System.out.println(Arrays.equals(numbers, numbers2));
}
}
الإخراج: صحيح بالمناسبة، فئة المصفوفات لا تعمل فقط مع المصفوفات العادية، ولكن أيضًا مع المصفوفات ثنائية الأبعاد:
public class Main {
public static void main(String[] args) {
int[][] numbers = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] numbersCopy = Arrays.copyOf(numbers, numbers.length);
System.out.println("Are these two-dimensional arrays equal?");
System.out.println(Arrays.deepEquals(numbers, numbersCopy));
System.out.println(Arrays.deepToString(numbersCopy));
}
}
الإخراج: هل هذه المصفوفات ثنائية الأبعاد متساوية؟ صحيح [[1، 2، 3]، [4، 5، 6]، [7، 8، 9]] كما ترى، تمكنت طريقة Arrays.copyOf() من نسخ مصفوفة ثنائية الأبعاد. وللفصل طرق خاصة لمقارنة وعرض المصفوفات ثنائية الأبعاد: DeepEquals و deepToString() . في المستقبل، سترى مرارًا وتكرارًا (وتبتهج بحقيقة ذلك) أن منشئي Java توقعوا الكثير من المواقف التي يواجهها المبرمجون بشكل متكرر، وقاموا بتنفيذ حلول جاهزة لهم في اللغة. يعد استخدام هذه الحلول أسهل وأكثر ملاءمة من إعادة اختراع العجلة، أليس كذلك؟ :) تأكد من قراءة الوثائق الخاصة بفئة المصفوفات على موقع Oracle
الإلكتروني. حظ موفق في دراستك!
GO TO FULL VERSION