إتقان Java Collections

يعتمد معظم المطورين بشكل افتراضي على ArrayList أو HashSet. هذا يعمل في المهام البسيطة، لكنه يفشل عندما تحتاج إلى السرعة أو التوسع.

قمت ذات مرة ببناء لوحة صدارة (leaderboard) للعبة باستخدام ArrayList عادية. كنت أقوم بفرزها في كل مرة تتغير فيها النتيجة، مما أدى إلى تجمد واجهة المستخدم باستمرار. كنت أحارب اللغة بدلاً من استخدامها.

توقف عن استخدام الأدوات الخاطئة. استخدم هذه المجموعات (collections) الثلاث المتخصصة لكتابة كود أسرع وأنظف.

  1. EnumSet لثوابت Enum

إذا استخدمت HashSet للـ enums، فستدفع ضريبة في الأداء. فكل عملية إدراج تقوم بتحويل الـ enum إلى كائن (boxing)، مما يضيف عبئاً غير ضروري.

يستخدم EnumSet ناقل بتات (bit vector)، ويقوم بإجراء الفحوصات باستخدام تعليمات وحدة المعالجة المركزية (CPU instruction) واحدة.

قبل: Set abilities = new HashSet<>(); abilities.add(Ability.FIRE);

بعد: EnumSet abilities = EnumSet.of(Ability.FIRE);

  1. NavigableSet لاستعلامات النطاق (Range Queries)

إن المرور يدوياً عبر قائمة مرتبة للعثور على نطاق معين هو أمر بطيء وعرضة للأخطاء، وغالباً ما ينتهي بك الأمر بأخطاء "الفرق بمقدار واحد" (off-by-one bugs).

يحافظ NavigableSet على بياناتك مرتبة تلقائياً، ويوفر عمليات بحث بتعقيد O(log n) للمجموعات الفرعية.

قبل: Collections.sort(scores); List topTen = scores.subList(size - 10, size);

بعد: NavigableSet scores = new TreeSet<>(Comparator.reverseOrder()); scores.add(1542); NavigableSet topTen = scores.headSet(scores.first(), true).stream().limit(10).collect(Collectors.toCollection(TreeSet::new));

  1. CopyOnWriteArrayList للقوائم التي يكثر فيها القراءة (Read-Heavy Lists)

إن استخدام كتل المزامنة (synchronized blocks) على ArrayList يبطئ كل عملية قراءة، كما يتسبب في حدوث ConcurrentModificationException إذا قام أحد الخيوط (threads) بالكتابة بينما يقوم خيط آخر بالقراءة.

يقوم CopyOnWriteArrayList بإنشاء نسخة جديدة من المصفوفة عند كل عملية كتابة، بينما يقرأ المستخدمون لقطة (snapshot) من المصفوفة.

قبل: List log = Collections.synchronizedList(new ArrayList<>()); // Iterating here can crash if a writer joins in.

بعد: CopyOnWriteArrayList log = new CopyOnWriteArrayList<>(); // Iteration is safe and never crashes.

توقف عن استخدام نفس المجموعتين (collections) كخيار افتراضي. اختر الأداة التي تتوافق مع نمط بياناتك.

المصدر: https://dev.to/timevolt/the-java-collections-force-mastering-the-hidden-gems-like-a-jedi-4438