مقدمة
الكلاس LinkedList
يستخدم لإنشاء مصفوفات متطورة مقارنةً مع المصفوفات العادية Arrays, حيث يوفر لك مجموعة من الدوال التي تمكنك من البحث فيها, التشييك على عناصرها, إضافة عناصر جديدة, حذف عناصر منها, و معالجة أكثر من عنصر فيها في نفس الوقت إلخ..
أهم ميزة في المصفوفات التي نوعها LinkedList
هي أن عدد العناصر فيها غير ثابت, حيث أنه يزيد عند إضافة عنصر جديد فيها و ينقص عند حذف عنصر منها بشكل تلقائي, و هذه الميزة غير موجودة في المصفوفات العادية.
كما أنك تستطيع الوصول للعناصر الموجودة فيها عن طريق أرقام الـ Index التي تعطى بالترتيب لكل عنصر يضاف فيها.
بناؤه
public class LinkedList<E>
extends AbstractSequentialList<E>
implements<E>, Deque<E>, Cloneable, Serializable
إذاً الكلاس LinkedList
يرث من الكلاس AbstractSequentialList
, و يطبق الإنترفيسات List
- Deque
- Cloneable
- Serializable
.
الفرق بين الكلاس LinkedList
و الكلاس ArrayList
الكلاس LinkedList
يشبه كثيراً الكلاس ArrayList
, الفرق بينهما هو التالي:
- مترجم لغة جافا يعامل الكلاس
LinkedList
بشكل أسرع من الكلاس ArrayList
.
- الكلاس
LinkedList
يملك دوال للحذف و الإضافة ليست موجودة في الكلاس ArrayList
.
- الكلاس
LinkedList
يحتل مساحة أكبر في الذاكرة مقارنةً مع المساحة التي يحتلها الكلاس ArrayList
.
أمثلة شاملة
في كل مثال موضوع استخدامنا كونستركتور مختلف و دوال جديدة.
المثال الأول
في المثال التالي قمنا بتعريف كائن نوعه LinkedList
أدخلنا فيه 6 عناصر ثم حذفنا منه عنصرين.
استخدامنا الدوال التالية: add()
- addFirst()
- addLast()
- remove()
- size()
.
Main.java
import java.util.LinkedList; // LinkedList هنا قمنا باستدعاء الكلاس
public class Main {
public static void main(String[] args) {
// arr إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
LinkedList arr = new LinkedList();
// و عرض عددهم arr هنا قمنا بعرض عناصر الكائن
System.out.println("All elements: " + arr);
System.out.println("Number of elements: " + arr.size() + "\n");
arr.add("B"); // [B] ==> arr في العنصر الكائن B هنا قمنا بإضافة الكائن
arr.add("C"); // [B, C] ==> arr في العنصر الكائن C هنا قمنا بإضافة الكائن
arr.add("E"); // [B, C, E] ==> arr في العنصر الكائن E هنا قمنا بإضافة الكائن
arr.add(2, "D"); // [B, C, D, E] ==> arr في العنصر الثالث في الكائن D هنا قمنا بإضافة الكائن
arr.addFirst("A"); // [A, B, C, D, E] ==> arr في أول عنصر في الكائن A هنا قمنا بإضافة الكائن
arr.addLast("F"); // [A, B, C, D, E, F] ==> arr في آخر الكائن F هنا قمنا بإضافة الكائن
// و عرض عددهم arr هنا قمنا بعرض عناصر الكائن
System.out.println("All elements: " + arr);
System.out.println("Number of elements: " + arr.size() + "\n");
arr.remove(); // [B, C, D, E, F] ==> arr هنا قمنا بحذف أول عنصر موجود في الكائن
arr.remove(2); // [B, C, E, F] ==> arr هنا قمنا بحذف العنصر الثالث في الكائن
arr.remove("B"); // [C, E, F] ==> arr في الكائن B هنا قمنا بحذف العنصر الذي يملك الكائن
// و عرض عددهم arr هنا قمنا بعرض عناصر الكائن
System.out.println("All elements: " + arr);
System.out.println("Number of elements: " + arr.size() + "\n");
}
}
سنحصل على النتيجة التالية عند التشغيل.
All elements: []
Number of elements: 0
All elements: [A, B, C, D, E]
Number of elements: 5
All elements: [A, D, E]
Number of elements: 3
المثال الثاني
في المثال التالي قمنا بإضافة كائن نوعه LinkedList
في كائن آخر نوعه LinkedList
.
لاحظ هنا أنه عند إضافة كائن بواسطة الدالة add(Collection c)
فإن جميع عناصره توضع في عنصر واحد.
Main.java
import java.util.LinkedList; // LinkedList هنا قمنا باستدعاء الكلاس
public class Main {
public static void main(String[] args) {
// arr1 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
LinkedList arr1 = new LinkedList();
// arr1 هنا قمنا بإضافة 5 عناصر في الكائن
arr1.add("A");
arr1.add("B");
arr1.add("C");
arr1.add("D");
arr1.add("E");
// arr2 إسمه LinkedList هنا قمنا بإنشاء كائن آخر من الكلاسList
LinkedList arr2 = new LinkedList();
// arr2 في أول عنصر في الكائن arr1 هنا قمنا بإضافة جميع عناصر الكائن
arr2.add(arr1);
// arr1 و الذي يمثل مصفوفة تحتوي على جميع عناصر الكائن arr2 هنا قمنا بطباعة العنصر الأول الموجود في الكائن
System.out.println("arr2 elements: " + arr2.get(0) + "\n");
// arr2 هنا قمنا بعرض عدد عناصر الكائن
System.out.println("Number of elements in arr2 : " + arr2.size());
}
}
سنحصل على النتيجة التالية عند التشغيل.
arr2 elements: [A, B, C, D, E]
Number of elements in arr2 : 1
المثال الثالث
في المثال التالي قمنا بتمرير كائن نوعه LinkedList
في كونستركتور كائن آخر نوعه LinkedList
.
لاحظ هنا أن جميع عناصر الكائن الأول ستوضع بنفس الترتيب في الكائن الثاني, و سيوضع كل كائن في عنصر أيضاً.
Main.java
import java.util.LinkedList; // LinkedList هنا قمنا باستدعاء الكلاس
public class Main {
public static void main(String[] args) {
// arr1 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
LinkedList arr1 = new LinkedList();
// arr1 هنا قمنا بإضافة 5 عناصر في الكائن
arr1.add("A");
arr1.add("B");
arr1.add("C");
arr1.add("D");
arr1.add("E");
// arr1 يحتوي على جميع عناصر الكائن arr2 إسمه LinkedList هنا قمنا بإنشاء كائن آخر من الكلاس
LinkedList arr2 = new LinkedList(arr1);
// arr2 هنا قمنا بإضافة عنصر جديد في الكائن
arr2.add("F");
// arr2 و arr1 هنا عرضنا جميع العناصر الموجودة في الكائنين
System.out.println("arr1 elements: " + arr1);
System.out.println("arr2 elements: " + arr2);
}
}
سنحصل على النتيجة التالية عند التشغيل.
arr1 elements: [A, B, C, D, E]
arr2 elements: [A, B, C, D, E, F]
المثال الرابع
في المثال التالي قمنا باستخدام الدوال التي تستخدم في البحث و التشييك.
استخدامنا الدوال التالية: add()
- get()
- getFirst()
- getLast()
- size()
- indexOf()
- lastIndexOf()
- contains()
.
Main.java
import java.util.LinkedList; // LinkedList هنا قمنا باستدعاء الكلاس
public class Main {
public static void main(String[] args) {
// arr إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
LinkedList arr = new LinkedList();
// arr هنا قمنا بإضافة 9 عناصر في الكائن
arr.add("A");
arr.add("B");
arr.add("C");
arr.add("D");
arr.add("E");
arr.add("A");
arr.add("B");
arr.add("C");
arr.add("Z");
// arr هنا عرضنا العنصر الأول في الكائن
System.out.println("First element: " + arr.getFirst());
// arr هنا عرضنا العنصر الأخير في الكائن
System.out.println("Last element: " + arr.getLast() + "\n");
// arr هنا عرضنا خامس عنصر موجود في الكائن
System.out.println("Element at al[4]: " + arr.get(4) + "\n");
// arr موجودين في الكائن 'C' أول و آخر كائن index هنا عرضنا
System.out.println("First index of the object 'C': " + arr.indexOf("C"));
System.out.println("Last index of the object 'C': " + arr.lastIndexOf("C") + "\n");
// F و D عن الكائنين arr هنا بحثنا في عناصر الكائن
System.out.println("Does it contain a 'D' object? " + arr.contains("D"));
System.out.println("Does it contain a 'F' object? " + arr.contains("F"));
}
}
سنحصل على النتيجة التالية عند التشغيل.
First element: A
Last element: Z
Element at al[4]: E
First index of the object 'C': 2
Last index of the object 'C': 7
Does it contain a 'D' object? true
Does it contain a 'F' object? false
المثال الخامس
في المثال التالي قمنا بنسخ عناصر كائن الـ LinkedList
بداخل مصفوفة جديدة نوعها Object
بواسطة الدالة toArray()
.
Main.java
import java.util.LinkedList; // LinkedList هنا قمنا باستدعاء الكلاس
public class Main {
public static void main(String[] args) {
// arr1 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
LinkedList arr1 = new LinkedList();
// arr1 هنا قمنا بإضافة 3 عناصر في الكائن
arr1.add("A");
arr1.add("B");
arr1.add("C");
// arr1 عدد عناصرها يساوي عدد عناصر الكائن ,Object نوعها ,arr2 هنا قمنا بإنشاء مصفوفة إسمها
Object[] arr2 = new Object[arr1.size()];
// arr2 بنفس الترتيب في المصفوفة arr1 هنا قمنا بنسخ عناصر الكائن
arr1.toArray(arr2);
// arr2 هنا أنشأنا حلقة تعرض جميع العناصر الموجودة في الحلقة
for(int i=0; i<arr2.length; i++) {
System.out.println("arr2[" +i+ "] = " +arr2[i]);
}
}
}
سنحصل على النتيجة التالية عند التشغيل.
arr2[0] = A
arr2[1] = B
arr2[2] = C
المثال السادس
في المثال التالي قمنا بإنشاء نسخة ثانية من كائن الـ LinkedList
في كائن جديد نوعه Object
بواسطة الدالة clone()
, بعدها قمنا بمسح كائن الـ LinkedList
الأصلي.
إنتبه: النسخة التي أنشأناها هنا تعتبر مجرد صورة للأشياء الموجودة في كائن الـ LinkedList
.
Main.java
import java.util.LinkedList; // LinkedList هنا قمنا باستدعاء الكلاس
public class Main {
public static void main(String[] args) {
// arr إسمه Linkedهنا قمنا بإنشاء كائن من الكلاس
LinkedList arr = new LinkedList();
// arr هنا قمنا بإضافة 3 عناصر في الكائن
arr.add("A");
arr.add("B");
arr.add("C");
// o في الكائن arr هنا قمنا بنسخ عناصر الكائن
Object o = arr.clone();
// arr هنا قمنا بمسح جميع عناصر الكائن
arr.clear();
// o و arr هنا قمنا بعرض عناصر كل من الكائنات
System.out.println("arr = " +arr);
System.out.println("o = " +o);
}
}
سنحصل على النتيجة التالية عند التشغيل.
arr = []
o = [A, B, C]
المثال السابع
في المثال التالي قمنا بتحديد نوع الكائنات التي يمكن إدخالها في كائنات الـ LinkedList
من خلال تطبيق مبدأ الـ Generics.
ملاحظة: سنشرح الـ Generics في درس خاص و هذا مجرد مثال بسيط.
Main.java
import java.util.LinkedList; // Linkedهنا قمنا باستدعاء الكلاس
public class Main {
public static void main(String[] args) {
// يمكنه تخزين كائنات من أي نوع كان arr1 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
LinkedList arr1 = new LinkedList();
// فقط String يمكنه تخزين كائنات من النوع arr2 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاسList
LinkedList<String> arr2 = new LinkedList<>();
// فقط Integer يمكنه تخزين كائنات من النوع arr3 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
LinkedList<Integer> arr3 = new LinkedList<>();
// arr1 هنا قمنا بإضافة 5 عناصر لها أنواع مختلفة في الكائن
arr1.add(null);
arr1.add(true);
arr1.add(1234);
arr1.add("java");
arr1.add('A');
// arr2 في الكائن String هنا قمنا بإضافة 3 عناصر نوعها
arr2.add("A");
arr2.add("B");
arr2.add("C");
// arr3 في الكائن int هنا قمنا بإضافة 3 عناصر نوعها
arr3.add(1);
arr3.add(2);
arr3.add(3);
// arr1 هنا قمنا بعرض عناصر الكائن
System.out.println("arr1: " +arr1);
// arr2 هنا قمنا بعرض عناصر الكائن
System.out.println("arr2: " +arr2);
// arr3 هنا قمنا بعرض عناصر الكائن
System.out.println("arr3: " +arr3);
}
}
سنحصل على النتيجة التالية عند التشغيل.
arr1: [null, true, 1234, java, A]
arr2: [A, B, C]
arr3: [1, 2, 3]