1. لاعتبارات الأداء، يفضل استخدام المصفوفات
يتم استخدام المصفوفات بشكل أقل وأقل في تطوير المشاريع، خاصة في التطوير الموجه للأعمال. أولاً، لا تحتوي المصفوفات على العديد من الطرق التي توفرها المجموعات مثل القائمة والإعدادات، ويجب عليك كتابة خوارزميات البحث والإضافة بنفسك ومع ذلك، نظرًا لأن المجموعات مثل القائمة والإعدادات تستخدم دعمًا عامًا، يتم تخزينها جميعًا في فئات مجمعة، ويمكن للمصفوفات استخدام أنواع البيانات الأساسية، وتكون سرعة تنفيذ أنواع البيانات الأساسية أسرع بكثير من أنواع المجمعات. ويتم تنفيذ الطبقة السفلية من فئة التجميع أيضًا من خلال المصفوفات.
2. إذا لزم الأمر، استخدم صفائف متغيرة الطول
عند تعلم فئات التجميع، يرغب العديد من الأشخاص في مقارنة الطول الثابت للمصفوفة بالطول المتغير لنوع المجموعة، ولكن في الواقع هذه المقارنة غير مناسبة من خلال مراقبة تنفيذ فئات التجميع مثل ArrayList، يمكننا أن نرى ذلك بالفعل يصبح ما يسمى بالمجموعة أطول في الواقع، فهو يوسع المصفوفة الأصلية بطريقة لبقة.
انسخ رمز الكود كما يلي:
عام ثابت T[] توسيع السعة (T[] بيانات، int newLength) {
// تحديد ما إذا كانت قيمة سلبية
newLength = newLength < 0 ? : newLength;
// أنشئ مصفوفة جديدة، وانسخ القيمة الأصلية وحدد الطول
return Arrays.copyOf(data, newLength);
}
عندما تكون متطلبات الأداء عالية، يمكنك التفكير في تغليف المصفوفات، فالطول الثابت للمصفوفة ليس عذرًا لعدم استخدامها.
3. كن حذرًا من النسخ الضحلة من المصفوفات
النسخة الضحلة من المصفوفة هي أيضًا أساس برمجة Java. النسخة الضحلة تعني أنه عند نسخ مصفوفة، يقوم النوع الأساسي بنسخ القيمة، بينما يقوم النوع المرجعي بنسخ العنوان المرجعي. في المثال أعلاه، يتم نسخ المصفوفة باستخدام Arrays.copyOf هي نسخة ضحلة، لذا عليك الانتباه عند استخدامها.
4. ضمن سيناريوهات واضحة، حدد السعة الأولية للمجموعة
في استخدامنا اليومي، نظرًا لأن طول نوع المجموعة يتغير تلقائيًا، فلن يتم إرفاق القيمة الأولية بفئة المجموعة عند إنشاء كائن. لنأخذ قائمة ArrayList الأكثر استخدامًا كمثال، نحتاج أولاً إلى معرفة ذلك عند إنشاء كائن يتم الوصول إلى السعة عند النقطة الحرجة، وستكون المصفوفة الأساسية كذلك تنشئ عملية CopyOf مصفوفة جديدة، وتكون سعة المصفوفة الجديدة 1.5 مرة من المصفوفة القديمة، وطول المصفوفة الافتراضي هو 10. عندما نعلم بوضوح أن كمية البيانات التي سيتم وضعها في الحاوية كبيرة، يجب أن نحدد القيمة الأولية لتجنب الحمل الزائد للأداء الناتج عن استخدام أوقات النسخ
5. اختر الخوارزمية المثالية المناسبة
البحث عن الحد الأقصى أو الأدنى لقيمة البيانات هو المعرفة الأساسية لبنية البيانات. لدينا أيضًا العديد من الطرق لتنفيذها في Java، وإليك خوارزميتين:
انسخ رمز الكود كما يلي:
public static int getMaxByArray(int[] data) {
// أبسط طريقة بحث ذاتية التنفيذ
int max = data[0];
لـ (int i = 1, size = data. length; i < size; i++) {
الحد الأقصى = الحد الأقصى <أنا؟
}
العودة ماكس؛
}
انسخ رمز الكود كما يلي:
public static int getMaxByArray(int[] data) {
// قم بالفرز أولاً ثم احصل على الجزء الأخير
Arrays.sort(data);
إرجاع البيانات[data.length - 1]؛
}
6. مصيدة تحويل مصفوفة النوع الأساسي!
يرجى مراعاة الكود التالي
انسخ رمز الكود كما يلي:
public static void main(String[] args) {
int[] nums = new int[] { 1, 2, 3, 4, 5 };
قائمة القائمة = Arrays.asList(nums);
System.out.println(list.size());
// حجم الإخراج في هذا الوقت هو 1
}
وكانت النتيجة التي توقعناها هي تحويل العناصر الموجودة في المصفوفة إلى فئة مجموعة من خلال Arrays.asList، ولكن على عكس التوقعات، أضفنا المصفوفة نفسها فقط ولم نفصل القيم في المصفوفة في هذا الوقت. إذا كانت إضافة الأدوية العامة إلى القائمة ستعطي رسالة خطأ أثناء التجميع، أو يمكن أن يؤدي تغيير المصفوفة نفسها إلى عدد صحيح إلى حل المشكلة.
7. لا يمكن تغيير كائن القائمة الذي تم إنشاؤه بواسطة طريقة asList.
من خلال المثال أعلاه، يمكننا أن نرى أن استخدام طريقة Arrays.asList يمكن أن يحول المصفوفة إلى قائمة، فما الذي يميز القائمة التي يتم إرجاعها بواسطة طريقة asList؟ لاحظ أن القائمة التي تم إرجاعها لا تدعم التغييرات لأن طريقة asList تُرجع ليس java.util.ArrayList، ولكن Array فئة داخلية خاصة ثابتة في فئة الأداة s، على الرغم من أنها تحتوي على نفس فئة AbstractList الأصلية مثل ArrayList، ولكن عند تجاوز الإضافة والطرق الأخرى، يتم طرح UnsupportedOperationException. هذه الفئة الداخلية الخاصة الثابتة تنفذ فقط الحجم، toArray، Get، الذي يحتوي على هذه طُرق
8. استخدم طرق اجتياز مختلفة لهياكل البيانات المختلفة
يرجى مشاهدة الكود التالي
انسخ رمز الكود كما يلي:
public static void main(String[] args) {
// فيما يلي طريقة الاجتياز لمجموعة ArrayList
العدد الصحيح = 80 * 10000؛
List arrayList = new ArrayList(num);
for (int i = 0, size = arrayList.size(); i < size; i++) {
arrayList.get(i);
}
// فيما يلي طريقة اجتياز مجموعة LinkedList
القائمة المرتبطة = قائمة مرتبطة جديدة () ؛
لـ (عدد صحيح: قائمة مرتبطة) {
}
}
لماذا تختار طرق اجتياز مختلفة لـ LinkedList وArrayList؟
1. نظرًا لأن ArrayList يطبق واجهة RamdomAccess (واجهة الوصول العشوائي)، فإن واجهة RamdomAccess هي نفس واجهة وضع العلامات في Java مثل الواجهات القابلة للتسلسل والقابلة للاستنساخ، مما يعني أنه يمكن الوصول إلى هذه الفئة بشكل عشوائي بالنسبة لـ ArrayList، وهذا يعني أنه يوجد بين البيانات لا يوجد ارتباط، أي أن الموضعين المتجاورين ليس لهما علاقة ترابط ويمكن الوصول إليهما بشكل عشوائي.
2. بناء جملة foreach في Java هو استخدام مختلف للمكرر (المكرر). نحن نعلم أن المكرر هو أحد أنماط التصميم الـ 23، لكن المكرر يحتاج إلى معرفة العلاقة الزمنية بين عنصرين، وإلا كيف يمكن تقديم دعم hasNext؟ ذلك لأن العنصر السابق يحتاج إلى تحديد ما إذا كان العنصر التالي موجودًا أم لا، ويتم إنشاء هذه العلاقة بالقوة، مما ينتهك الخصائص الخاصة للوصول العشوائي لـ ArrayList.
3. في LinkedList، لأنه يتم تخزينه في شكل قائمة مرتبطة بشكل مزدوج، فإن دعم التكرارات جيد جدًا نظرًا لوجود علاقة متأصلة بين عنصرين متجاورين في LinkedList، يجب اعتماد طرق اجتياز مختلفة لـ LinkedList وArrayList. يمكن للقراء المهتمين تجربة الوصول إلى LinkedList في شكل اشتراكات، وسيجدون أن هناك فجوة كبيرة في الكفاءة بين الاثنين.
8. اختر ArrayList أو LinkedList عندما يكون ذلك مناسبًا
الاختلافات الرئيسية بين ArrayList وLinkedList:
1. بنية البيانات الأساسية لـ ArrayList هي مصفوفة، في حين أن البنية الأساسية لـ LinkedList هي قائمة مرتبطة بشكل مزدوج.
2. عند إدراج البيانات، نظرًا لأن ArrayList يحتاج إلى نقل عناصر المصفوفة للخلف بعد كل عملية إدراج، فإن LinkedList يحتاج فقط إلى تغيير العقدة الرئيسية والعقدة الخلفية لإكمال عملية الإدراج، لذلك عندما تكون عمليات الإدراج أكثر تكرارًا، يُفضل LinkedList.
3. عند حذف البيانات، لأن ArrayList يحتاج إلى الحفاظ على ترتيب المصفوفة، يجب أيضًا إزاحة العناصر للخلف أو للأمام بعد الحذف، بينما لا يزال LinkedList يغير العقد الرأسية والذيلية.
4. عند التحديث، نظرًا لأن LinkedList سيستخدم طريقة نصف الاجتياز للعثور على العنصر المحدد ثم تحديثه، مقارنةً بالاستبدال المباشر لـ ArrayList لعناصر النص المنخفض الموضوعة، فإن ArrayList أكثر كفاءة في التحديث.
5. يمكن لـ LinkedList محاكاة قائمة الانتظار من خلال عمليات مثل addFirst و addLast من LinkedList.
9. عندما تكون القوائم متساوية، ما عليك سوى الاهتمام ببيانات العنصر
لكي نتمكن من برمجة واجهات مثل القائمة والضبط والخريطة براحة البال، قامت Java بتجاوز المعادلات في فئة المجموعة، لذلك عند مقارنة ما إذا كانت مجموعتان متساويتان، نحتاج فقط إلى مقارنة ما إذا كانت بيانات العنصر متساوية يؤدي هذا إلى تجنب إصلاح كود Java الخاطئ الناتج عن استبدال فئة تنفيذ المجموعة
انسخ رمز الكود كما يلي:
public static void main(String[] args) {
List arrayList = new ArrayList();
arrayList.add(1);
arrayList.add(2);
القائمة المرتبطة = قائمة مرتبطة جديدة () ؛
LinkedList.add(1);
LinkedList.add(2);
System.out.println(arrayList.equals(linkedList));
// لا تهتم بالتنفيذ المحدد، فالنتيجة صحيحة
}