LinkedList أو ArrayList في Java: أيهما تختار ولماذا هذا مهم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

LinkedList أو ArrayList: معركة عمالقة المجموعات في Java

\n\n

إذا كنت قد كتبت كود Java يعمل مع قوائم البيانات من قبل، فبالتأكيد واجهت المعضلة: LinkedList أم ArrayList؟ هذا السؤال هو ضربة حقيقية على Stack Overflow، يناقشه آلاف المطورين. وليس من العبث. اختيار هيكل البيانات الخاطئ يمكن أن يحول كودك السريع إلى سلحفاة تزحف في المستنقع. بينما الاختيار الصحيح يمكن أن يجعل التطبيق سريع الاستجابة وفعالاً.

\n\n

اليوم لن نعدد الحقائق الجافة فقط. سننظر تحت الغطاء في Java، ونفهم كيف تعمل هذه المجموعات على مستوى الذاكرة والمعالج، ونعطي إجابة واضحة: متى يجب استخدام LinkedList، ومتى يجب استخدام ArrayList؟ هيا بنا!

\n\n

باختصار عن المهم: ماذا يقول السادة في التوثيق

\n\n

لنبدأ بالأساسيات. كلا الفئتين تنفذان واجهة List، لكنهما تفعلان ذلك بطرق مختلفة.

\n\n
    \n
  • ArrayList هو مصفوفة ديناميكية. يخزن العناصر في كتلة ذاكرة متصلة. عندما تمتلئ المصفوفة، يقوم بإنشاء مصفوفة جديدة أكبر حجماً وينسخ إليها جميع العناصر.
  • \n
  • LinkedList هو قائمة مرتبطة مزدوجة. كل عنصر (عقدة) يخزن مراجع للعنصر السابق والتالي. يتم تخصيص الذاكرة لكل عقدة على حدة.
  • \n
\n\n

يبدو الأمر بسيطاً. لكن الشيطان، كما هو الحال دائماً، في التفاصيل. دعنا نلقي نظرة على الكود.

\n\n

تحت الغطاء: كيف يعمل هذا عملياً

\n\n

ArrayList: سرعة الوصول، لكن إدخال بطيء في المنتصف

\n\n
import java.util.ArrayList;\nimport java.util.List;\n\npublic class ArrayListDemo {\n    public static void main(String[] args) {\n        List<String> arrayList = new ArrayList<>();\n        \n        // الإضافة في النهاية — سريعة (O(1) معدلة)\n        long start = System.nanoTime();\n        for (int i = 0; i < 100000; i++) {\n            arrayList.add("Element " + i);\n        }\n        long end = System.nanoTime();\n        System.out.println("ArrayList add (في النهاية): " + (end - start) / 1e6 + " ms");\n        \n        // الوصول حسب الفهرس — فوري (O(1))\n        start = System.nanoTime();\n        String element = arrayList.get(50000);\n        end = System.nanoTime();\n        System.out.println("ArrayList get: " + (end - start) + " ns");\n        \n        // الإدخال في المنتصف — بطيء (O(n))\n        start = System.nanoTime();\n        arrayList.add(25000, "INSERTED");\n        end = System.nanoTime();\n        System.out.println("ArrayList insert (المنتصف): " + (end - start) / 1e6 + " ms");\n    }\n}
\n\n

ماذا يحدث هنا؟ عندما تقوم بإدخال عنصر في منتصف ArrayList، فإن جميع العناصر الموجودة على يمين نقطة الإدخال تنتقل موضعاً واحداً. هذه عملية O(n). إذا كان لديك مليون عنصر، فستكون مليون عملية نسخ. مؤلم.

\n\n

LinkedList: الإدخال هو الملك، لكن الوصول هو المنبوذ

\n\n
import java.util.LinkedList;\nimport java.util.List;\n\npublic class LinkedListDemo {\n    public static void main(String[] args) {\n        List<String> linkedList = new LinkedList<>();\n        \n        // الإضافة في النهاية — سريعة (O(1))\n        long start = System.nanoTime();\n        for (int i = 0; i < 100000; i++) {\n            linkedList.add("Element " + i);\n        }\n        long end = System.nanoTime();\n        System.out.println("LinkedList add (في النهاية): " + (end - start) / 1e6 + " ms");\n        \n        // الوصول حسب الفهرس — بطيء (O(n))\n        start = System.nanoTime();\n        String element = linkedList.get(50000);\n        end = System.nanoTime();\n        System.out.println("LinkedList get: " + (end - start) / 1e6 + " ms");\n        \n        // الإدخال في المنتصف — سريع (O(1) بعد البحث عن الموضع)\n        start = System.nanoTime();\n        // ملاحظة: طريقة add(index, element) نفسها لا تزال تقوم بالبحث (O(n))\n        linkedList                

المدونات

توصيات الكتب