مرحبًا! في السابق، أثناء التدريب، كنا نعمل مع كائنات فردية (أو أنواع بدائية). ولكن ماذا لو كنا بحاجة إلى العمل ليس مع كائن واحد، ولكن مع مجموعة كاملة؟ على سبيل المثال، نريد إنشاء قائمة بأعياد ميلاد جميع الموظفين في شركتنا. يجب أن تحتوي على 30 سطرًا على سبيل المثال بالتنسيق: "أندري بيتروف، 25 يناير". ستساعدنا بنية البيانات الخاصة، المصفوفة، هنا. إذا قارنت المصفوفة بكائنات من الحياة الواقعية، فستجد أن بنيتها تشبه إلى حد كبير قبو بنك يحتوي على خلايا: يتكون المصفوفة أيضًا من خلايا. يمكنك وضع شيء ما في كل خلية. في هذه الحالة، للوصول إلى المحتوى تحتاج إلى معرفة رقم الخلية. يتم إنشاء المصفوفة على النحو التالي:
public class Main {
public static void main(String[] args) {
String [] birthdays = new String[10]; // array of Java strings
}
}
لقد أنشأنا هنا مجموعة من 10 خلايا. يمكنك الانتباه على الفور إلى بعض ميزات المصفوفة:
- يقوم بتخزين البيانات من نوع محدد بدقة. إذا أنشأنا مصفوفة سلسلة في البداية
String
، فلن نتمكن من تخزين أي شيء آخر فيها. يتم تحديد نوع البيانات عند إنشاء المصفوفة. وهذا ما يميزه عن صندوق الأمانات، الذي يمكن للعميل أن يخزن فيه ما يريد. - يمكن للمصفوفة تخزين بيانات من أنواع بدائية (على سبيل المثال،
int
) أو سلاسل (String
) أو كائنات من نفس الفئة. بتعبير أدق، ولا حتى الكائنات نفسها، ولكن روابط لهذه الكائنات. - يجب تحديد حجم المصفوفة أثناء الإنشاء. لن تتمكن من تحديده لاحقًا أو تغيير حجمه بعد الإنشاء.
[]
على جانبي التعبير. يمكن تحديدها قبل اسم المتغير المرجعي أو بعده - وستعمل في كلتا الحالتين:
//Java arrays of strings, two syntaxes
String [] birthdays = new String[10];
String birthdays [] = new String[10];
إذا كنت تريد كتابة شيء ما في مصفوفة، فأنت بحاجة إلى تحديد رقم الخلية التي سيتم كتابة القيمة فيها. تبدأ أرقام خلايا المصفوفة عند 0. البدء من الصفر هو ممارسة شائعة في البرمجة. كلما اعتدت عليها بشكل أسرع، كان ذلك أفضل :) أي إذا كنت تريد وضع بعض القيمة في الخلية الأولى من المصفوفة ، فسيتم ذلك على النحو التالي:
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
}
}
الآن، تحتوي الخلية الأولى في المصفوفة، التي تحتوي على أعياد ميلاد الزملاء، على سلسلة تحتوي على تاريخ ميلاد لينا. وبالقياس، يمكنك إضافة قيم أخرى:
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
birthdays[1] = "Kolya Romanov, May 18";
birthdays[7] = "Olesya Ostapenko, January 3";
}
}
يرجى ملاحظة: أضفنا عيد ميلاد أوليسيا إلى الخلية الثامنة (هل نسيت لماذا الخلية رقم 7 هي الثامنة؟). على الرغم من عدم ملء جميع الخلايا الأخرى. ليس من الضروري كتابة القيم في المصفوفة بالترتيب - لا يوجد مثل هذا القيد. من ناحية أخرى، إذا كتبت بالترتيب، فسيكون من الأسهل بكثير تتبع عدد الخلايا الحرة والمشغولة، ولن يكون هناك "ثقوب" متبقية في المصفوفة. إذا كنت ترغب في الحصول على محتويات خلية المصفوفة، كما هو الحال في خلية البنك، فأنت بحاجة إلى معرفة رقمها. يتم ذلك على النحو التالي:
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
birthdays[1] = "Kolya Romanov, May 18";
birthdays[7] = "Olesya Ostapenko, January 3";
String olesyaBirthday = birthdays[7];
System.out.println(olesyaBirthday);
}
}
إخراج وحدة التحكم:
Олеся Остапенко, 3 января
لقد أنشأنا متغيرًا وأخبرنا String
المترجم: "ابحث عن الخلية ذات الفهرس 7 في المصفوفة birthdays
وقم بتعيين القيمة المخزنة هناك للمتغير String
olesyaBirthday
." هذا بالضبط ما فعله.
طول مصفوفة جافا
عند العمل مع مصفوفة، يمكنك بسهولة معرفة طولها باستخدام خاصية خاصة -length
.
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
birthdays[1] = "Kolya Romanov, May 18";
birthdays[7] = "Olesya Ostapenko, January 3";
int birthdaysLength = birthdays.length;
System.out.println(birthdaysLength);
}
}
إخراج وحدة التحكم:
10
ملحوظة:تقوم الخاصية length
بتخزين حجم المصفوفة، وليس عدد الخلايا المملوءة. يخزن مصفوفتنا ثلاث قيم فقط، ولكن عندما أنشأناها، حددنا الحجم = 10. هذه هي القيمة التي يُرجعها الحقل length
. لماذا قد يكون هذا مفيدا؟ حسنًا، على سبيل المثال، إذا كنت تريد طباعة قائمة بجميع أعياد الميلاد على وحدة التحكم (للتأكد من عدم نسيان أي شخص)، فيمكنك القيام بذلك في حلقة واحدة بسيطة:
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
birthdays[1] = "Kolya Romanov, May 18";
birthdays[2] = "Vika Ignatova, July 12";
birthdays[3] = "Denis Kozlov, September 7";
birthdays[4] = "Maxim Maslennikov, November 9";
birthdays[5] = "Roman Baranov, August 14";
birthdays[6] = "Valery Pyatkina, April 1";
birthdays[7] = "Olesya Ostapenko, January 3";
birthdays[8] = "Kostya Gurko, October 19";
birthdays[9] = "Seryozha Naumov, May 3";
for (int i = 0; i < birthdays.length; i++) {
System.out.println(birthdays[i]);
}
}
}
في الحلقة نقوم بإنشاء متغير i
يساوي في البداية الصفر. في كل تمريرة، نأخذ الخلية التي تحتوي على الفهرس i من المصفوفة الخاصة بنا ونطبع قيمتها على وحدة التحكم. ستقوم الحلقة بإجراء 10 تكرارات، وستزداد قيم i من 0 إلى 9 - فقط وفقًا لمؤشرات خلايا صفيفنا! بهذه الطريقة سنقوم بطباعة كافة القيم من birthdays[0]
إلى إلى وحدة التحكم birthdays[9]
، في الواقع هناك طرق لإنشاء مصفوفة بشكل مختلف. int
على سبيل المثال، يمكن إنشاء مجموعة من الأرقام على النحو التالي:
public class Main {
public static void main(String[] args) {
int numbers [] = {7, 12, 8, 4, 33, 79, 1, 16, 2};
}
}
تسمى هذه الطريقة "التهيئة السريعة". إنه أمر مريح للغاية حيث نقوم على الفور بإنشاء مصفوفة وملئها بالقيم. ليست هناك حاجة لتحديد حجم المصفوفة بشكل صريح - length
سيتم ملء الحقل تلقائيًا أثناء التهيئة السريعة.
public class Main {
public static void main(String[] args) {
int numbers [] = {7, 12, 8, 4, 33, 79, 1, 16, 2};
System.out.println(numbers.length);
}
}
إخراج وحدة التحكم:
9
مصفوفة كائنات جافا
لقد سمعت بالفعل أن مصفوفات الكائنات ومصفوفات الأوليات يتم تخزينها في الذاكرة بشكل مختلف. لنأخذ على سبيل المثال مصفوفة من ثلاثة كائناتCat
:
public class Cat {
private String name;
public Cat(String name) {
this.name = name;
}
public static void main(String[] args) {
Cat[] cats = new Cat[3];
cats[0] = new Cat("Thomas");
cats[1] = new Cat("Hippopotamus");
cats[2] = new Cat("Philip Markovich");
}
}
هناك بعض الأشياء التي يجب فهمها هنا:
- في حالة الأوليات، تقوم مصفوفات Java بتخزين العديد من القيم المحددة (مثل الأرقام
int
). في حالة الكائنات، تقوم المصفوفة بتخزين العديد من المراجع. يتكون المصفوفةcats
من ثلاث خلايا، تحتوي كل منها على مرجع إلى كائنCat
. يشير كل رابط إلى عنوان في الذاكرة حيث يتم تخزين هذا الكائن. - يتم تخزين عناصر المصفوفة في الذاكرة في كتلة واحدة. يتم ذلك من أجل الوصول إليها بشكل أكثر كفاءة وسرعة. وبالتالي، يشير الارتباط
cats
إلى كتلة في الذاكرة حيث يتم تخزين جميع الكائنات - عناصر المصفوفة. أcats[0]
- إلى عنوان محدد ضمن هذه الكتلة.
صفيف من المصفوفات أو صفيف ثنائي الأبعاد
وبناءً على ذلك، نواجه السؤال: هل يمكننا، على سبيل المثال، إنشاء مصفوفة من المصفوفات، وليس مصفوفة من السلاسل أو الأرقام؟ وسيكون الجواب - نعم نستطيع! يمكن للمصفوفة تخزين أي كائنات بداخلها، بما في ذلك المصفوفات الأخرى. سيتم تسمية مثل هذه المصفوفة ثنائية الأبعاد. إذا قمت بتصويره في صورة، فسوف يبدو مشابهًا جدًا للجدول العادي. على سبيل المثال، نريد إنشاء مصفوفة تقوم بتخزين 3 مصفوفات من الأرقامint
تحتوي كل منها على 10 خلايا. سيبدو كما يلي: يمثل كل سطر مجموعة من الأرقام int
. تحتوي المصفوفة الأولى على أرقام من 1 إلى 10، والثانية - من -1 إلى -10، والثالثة - مجموعة من الأرقام العشوائية. يتم تخزين كل من هذه المصفوفات في خلية من المصفوفة ثنائية الأبعاد. تبدو تهيئة مصفوفة ثنائية الأبعاد في التعليمات البرمجية كما يلي:
public static void main(String[] args) {
Cat[][] cats = new Cat[3][5];
}
تخزن مصفوفة القطط ثنائية الأبعاد الخاصة بنا 3 مصفوفات تحتوي كل منها على 5 خلايا. إذا أردنا وضع الكائن في الخلية الثالثة من المصفوفة الثانية، فإننا نفعل ذلك على النحو التالي:
public static void main(String[] args) {
Cat[][] cats = new Cat[3][5];
cats[1][2] = new Cat("Fluff");
}
[1]
يشير إلى الصفيف الثاني، [2]
ويشير إلى الخلية الثالثة من هذا الصفيف. نظرًا لأن المصفوفة ثنائية الأبعاد تتكون من عدة مصفوفات، فمن أجل اجتيازها وطباعة جميع القيم إلى وحدة التحكم (أو ملء جميع الخلايا)، نحتاج إلى حلقة مزدوجة متداخلة:
for (int i = 0; i < cats.length; i++) {
for (int j = 0; j < cats[i].length; j++) {
System.out.println(cats[i][j]);
}
}
في الحلقة الخارجية (المتغيرة i
)، نتناوب في عبور جميع المصفوفات التي تشكل المصفوفة ثنائية الأبعاد. في الحلقة الداخلية (المتغيرة j
) نقوم بالتكرار عبر جميع خلايا كل مصفوفة. ونتيجة لذلك، cats[0][0]
سيتم عرض الكائن (الصفيف الأول، الخلية الأولى) أولاً على وحدة التحكم، وسيكون الكائن الثاني cats[0][1]
(الصفيف الأول، الخلية الثانية). عند استنفاد المصفوفة الأولى، سيتم إخراج، و cats[1][0]
، وما إلى ذلك. بالمناسبة، التهيئة السريعة متاحة أيضًا للمصفوفات ثنائية الأبعاد: cats[1][1]
cats[1][2]
int[][] numbers = {{1,2,3}, {4,5,6}, {7,8,9}};
عادةً، نكتب مصفوفة ثنائية الأبعاد numbers
بالشكل int[3][3]
، لكن هذه الطريقة تسمح لنا بتحديد القيم على الفور. لماذا قد تكون هناك حاجة إلى مجموعة ثنائية الأبعاد؟ حسنًا، على سبيل المثال، بمساعدتها يمكنك بسهولة إعادة إنشاء اللعبة الشهيرة "سفينة حربية": هيكل الملعب في "سفينة حربية" يمكن وصفه بسهولة: مصفوفة ثنائية الأبعاد مكونة من 10 صفائف، 10 خلايا لكل منها . يمكنك إنشاء مصفوفتين من هذا القبيل - لنفسك ولخصمك:
int [][] seaBattle = new int[10][10];
int [][] seaBattle2 = new int[10][10];
تقوم بملء بعض القيم (على سبيل المثال، أرقام أو علامات *
) الخلايا التي توجد بها سفنك، ثم تتناوب أنت وخصمك في الاتصال بأرقام الخلايا:
- معركة البحر[6][5]!
- ماضي! معركة البحر 2 [6] [6]!
- مصاب!
- معركة البحر 2 [6] [7]!
- مصاب!
- معركة البحر 2[6][8]!,
- قتل!
موارد إضافية حول المصفوفات
هل تريد معرفة المزيد عن المصفوفات؟ يرجى إلقاء نظرة على المقالات أدناه. هناك الكثير من المعلومات المثيرة للاهتمام والمفيدة حول هذا الموضوع.- المصفوفات في Java - مقالة مفصلة عن المصفوفات وإنشائها وتهيئتها واستخدامها. مع الأمثلة.
- فئة المصفوفات واستخدامها - توضح المقالة بعض أساليب الفئة
Array
- المصفوفات هي أول محاضرة في JavaRush مخصصة للمصفوفات.
- المصفوفات متعددة الأبعاد - مقالة مفصلة عن المصفوفات متعددة الأبعاد مع أمثلة.
- إرجاع مصفوفة ذات طول صفري، وليست خالية - يتحدث مؤلف البرمجة الفعالة جوشوا بلوخ عن كيفية إرجاع المصفوفات الفارغة بشكل أفضل.
GO TO FULL VERSION