(मूल रूप से कई क्षेत्रों के आधार पर जावा में वस्तुओं की सूची को छाँटने के तरीके से )
इस जिस्ट में मूल कार्य कोड
जावा 8 लैम्ब्डा का उपयोग करना (10 अप्रैल 2019 को जोड़ा गया)
जावा 8 ने लैंबडा (गुवा और अपाचे कॉमन्स अभी भी अधिक लचीलेपन की पेशकश कर सकते हैं) द्वारा इसे अच्छी तरह से हल करता है:
Collections.sort(reportList, Comparator.comparing(Report::getReportKey)
.thenComparing(Report::getStudentNumber)
.thenComparing(Report::getSchool));
नीचे @ gaoagong के उत्तर के लिए धन्यवाद ।
ध्यान दें कि एक लाभ यह है कि गेटर्स का मूल्यांकन आलसी (जैसे। getSchool()
केवल प्रासंगिक होने पर मूल्यांकन किया जाता है) किया जाता है।
गन्दा और दृढ़: हाथ से छँटाई
Collections.sort(pizzas, new Comparator<Pizza>() {
@Override
public int compare(Pizza p1, Pizza p2) {
int sizeCmp = p1.size.compareTo(p2.size);
if (sizeCmp != 0) {
return sizeCmp;
}
int nrOfToppingsCmp = p1.nrOfToppings.compareTo(p2.nrOfToppings);
if (nrOfToppingsCmp != 0) {
return nrOfToppingsCmp;
}
return p1.name.compareTo(p2.name);
}
});
इसके लिए बहुत अधिक टाइपिंग, रखरखाव की आवश्यकता होती है और यह त्रुटि प्रवण है। एकमात्र लाभ यह है कि प्रासंगिक होने पर ही गेटर्स मंगवाए जाते हैं।
चिंतनशील तरीका: बीनकॉमपरेटर के साथ छंटनी
ComparatorChain chain = new ComparatorChain(Arrays.asList(
new BeanComparator("size"),
new BeanComparator("nrOfToppings"),
new BeanComparator("name")));
Collections.sort(pizzas, chain);
स्पष्ट रूप से यह अधिक संक्षिप्त है, लेकिन इससे भी अधिक त्रुटि की संभावना है क्योंकि आप स्ट्रिंग्स का उपयोग करके फ़ील्ड के लिए अपना प्रत्यक्ष संदर्भ खो देते हैं (कोई भी प्रकार, ऑटो-रिफैक्टरिंग नहीं)। अब यदि किसी फ़ील्ड का नाम बदला गया है, तो कंपाइलर किसी समस्या की रिपोर्ट भी नहीं करेगा। इसके अलावा, क्योंकि यह समाधान प्रतिबिंब का उपयोग करता है, छंटाई बहुत धीमी है।
वहां पहुंचना: Google अमरूद की तुलना के साथ छंटनी
Collections.sort(pizzas, new Comparator<Pizza>() {
@Override
public int compare(Pizza p1, Pizza p2) {
return ComparisonChain.start().compare(p1.size, p2.size).compare(p1.nrOfToppings, p2.nrOfToppings).compare(p1.name, p2.name).result();
}
});
यह बहुत बेहतर है, लेकिन सबसे आम उपयोग के मामले के लिए कुछ बॉयलर प्लेट कोड की आवश्यकता होती है: डिफ़ॉल्ट रूप से अशक्त मान कम होना चाहिए। अशक्त क्षेत्रों के लिए, आपको अमरूद को एक अतिरिक्त निर्देश देना होगा कि उस मामले में क्या करना है। यह एक लचीला तंत्र है यदि आप कुछ विशिष्ट करना चाहते हैं, लेकिन अक्सर आप डिफ़ॉल्ट केस (यानी 1, ए, बी, जेड, नल) चाहते हैं।
और जैसा कि नीचे टिप्पणी में कहा गया है, इन गेटर्स का मूल्यांकन प्रत्येक तुलना के लिए तुरंत किया जाता है।
अपाचे कॉमन्स के साथ छाँटना तुलनात्मकता
Collections.sort(pizzas, new Comparator<Pizza>() {
@Override
public int compare(Pizza p1, Pizza p2) {
return new CompareToBuilder().append(p1.size, p2.size).append(p1.nrOfToppings, p2.nrOfToppings).append(p1.name, p2.name).toComparison();
}
});
अमरूद की तुलना की तरह, यह पुस्तकालय वर्ग कई क्षेत्रों में आसानी से हल करता है, लेकिन यह शून्य मानों के लिए डिफ़ॉल्ट व्यवहार को भी परिभाषित करता है (जैसे 1, ए, बी, जेड, नल)। हालाँकि, आप कुछ भी निर्दिष्ट नहीं कर सकते, जब तक कि आप अपने स्वयं के तुलनित्र प्रदान न करें।
फिर से, जैसा कि नीचे टिप्पणी में कहा गया है, इन गेटर्स का मूल्यांकन प्रत्येक तुलना के लिए तुरंत किया जाता है।
इस प्रकार
अंततः यह स्वाद और लचीलेपन की आवश्यकता के लिए नीचे आता है (अमरूद की तुलना) बनाम संक्षिप्त कोड (Apache's ComparToBuilder)।
बोनस विधि
मुझे एक अच्छा समाधान मिला जो कोडरव्यू पर प्राथमिकता में क्रम में कई तुलनित्रों को जोड़ता है MultiComparator
:
class MultiComparator<T> implements Comparator<T> {
private final List<Comparator<T>> comparators;
public MultiComparator(List<Comparator<? super T>> comparators) {
this.comparators = comparators;
}
public MultiComparator(Comparator<? super T>... comparators) {
this(Arrays.asList(comparators));
}
public int compare(T o1, T o2) {
for (Comparator<T> c : comparators) {
int result = c.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
public static <T> void sort(List<T> list, Comparator<? super T>... comparators) {
Collections.sort(list, new MultiComparator<T>(comparators));
}
}
फ़ोकस अपाचे कॉमन्स कलेक्शंस का उपयोग इसके लिए पहले से ही है:
ComparatorUtils.chainedComparator (comparatorCollection)
Collections.sort(list, ComparatorUtils.chainedComparator(comparators));