𝗠𝗮𝘀𝘁𝗲𝗿 𝗝𝗮𝘃𝗮 𝗖𝗼𝗹𝗹𝗲𝗰𝘁𝗶𝗼𝗻𝘀
बहुतेक डेव्हलपर्स डिफॉल्टनुसार ArrayList किंवा HashSet वापरतात. साध्या कामांसाठी हे ठीक आहे. पण जेव्हा तुम्हाला वेग (speed) किंवा स्केल (scale) हवा असतो, तेव्हा हे अपयशी ठरते.
मी एकदा साध्या ArrayList चा वापर करून गेम लीडरबोर्ड बनवला होता. प्रत्येक वेळी स्कोअर बदलला की मी तो सॉर्ट (sort) करायचो. यामुळे UI सतत फ्रीझ होत असे. मी भाषेचा वापर करण्याऐवजी तिच्याशीच संघर्ष करत होतो.
चुकीची साधने वापरणे थांबवा. अधिक वेगवान आणि स्वच्छ कोड लिहिण्यासाठी या तीन विशेष (specialized) collections चा वापर करा.
- Enum Constants साठी EnumSet
जर तुम्ही enums साठी HashSet वापरले, तर तुम्हाला परफॉर्मन्सच्या बाबतीत किंमत मोजावी लागते. प्रत्येक इन्सर्शन (insertion) enum ला एका ऑब्जेक्टमध्ये रूपांतरित करते. यामुळे अनावश्यक ओव्हरहेड (overhead) वाढतो.
EnumSet एका bit vector चा वापर करते. ते एका सिंगल CPU इंस्ट्रक्शनचा वापर करून तपासणी करते.
- जेव्हा तुमच्याकडे enum व्हॅल्यूजचा एक निश्चित संच (fixed set) असतो, तेव्हा याचा वापर करा.
- हे garbage collection कमी करते.
- हे टाईट लूप्समध्ये (tight loops) १० पटीने वेग वाढवते.
Before:
Set<Ability> abilities = new HashSet<>();
abilities.add(Ability.FIRE);
After:
EnumSet<Ability> abilities = EnumSet.of(Ability.FIRE);
- Range Queries साठी NavigableSet
रेंज शोधण्यासाठी सॉर्ट केलेल्या लिस्टमधून मॅन्युअली लूप फिरवणे हे संथ असते आणि त्यात चुका होण्याची शक्यता असते. अनेकदा तुम्हाला 'off-by-one' सारखे बग्स आढळतात.
NavigableSet तुमचा डेटा आपोआप सॉर्ट करून ठेवते. ते subsets साठी O(log n) लुकअप प्रदान करते.
- हाय-स्कोअर टेबल्स किंवा किंमतीच्या रेंजसाठी (price ranges) याचा वापर करा.
- विशिष्ट रेंज मिळवण्यासाठी
headSet()किंवाsubSet()वापरा. - यामुळे मॅन्युअल सॉर्टिंग कोडची गरज उरत नाही.
Before:
Collections.sort(scores);
List<Integer> topTen = scores.subList(size - 10, size);
After:
NavigableSet<Integer> scores = new TreeSet<>(Comparator.reverseOrder());
scores.add(1542);
NavigableSet<Integer> topTen = scores.headSet(scores.first(), true).stream().limit(10).collect(Collectors.toCollection(TreeSet::new));
- Read-Heavy Lists साठी CopyOnWriteArrayList
ArrayList वर synchronized blocks वापरल्यामुळे प्रत्येक 'read' ऑपरेशन संथ होते. तसेच, जर एक thread डेटा लिहित असताना दुसरा thread डेटा वाचत असेल, तर ConcurrentModificationException येऊ शकते.
CopyOnWriteArrayList प्रत्येक 'write' वेळी ॲरेची एक नवीन कॉपी तयार करते. वाचणारे (Readers) ॲरेच्या स्नॅपशॉटला (snapshot) पाहतात.
- इव्हेंट लिसनर्स (event listeners) किंवा कॉन्फिगरेशन सेटिंग्ससाठी याचा वापर करा.
- जेव्हा 'reads' हे 'writes' पेक्षा खूप जास्त वेळा घडतात, तेव्हा याचा वापर करा.
- हे लॉक-फ्री (lock-free) रीड्सना परवानगी देते.
Before:
List<String> log = Collections.synchronizedList(new ArrayList<>());
// Iterating here can crash if a writer joins in.
After:
CopyOnWriteArrayList<String> 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