मैं विशेष रूप से स्थैतिक तरीकों का उपयोग करने के बारे में Collections.sortऔर के बीच अंतर को देख रहा हूं list.sort, Comparatorचाहे लंबोदर अभिव्यक्ति में परम प्रकार की आवश्यकता हो। शुरू करने से पहले, मुझे पता है कि मैं Song::getTitleअपनी समस्याओं को दूर करने के लिए विधि संदर्भों, उदाहरणों का उपयोग कर सकता हूं, लेकिन यहां मेरी क्वेरी इतनी अधिक नहीं है जिसे मैं ठीक करना चाहता हूं, लेकिन कुछ ऐसा है जिसका मुझे जवाब चाहिए, अर्थात जावा कंपाइलर इसे इस तरह से क्यों संभाल रहा है। ।
ये मेरी खोज हैं। मान लें कि हमारे पास कुछ ArrayListप्रकार हैं Song, कुछ गानों के साथ, 3 मानक तरीके हैं:
ArrayList<Song> playlist1 = new ArrayList<Song>();
//add some new Song objects
playlist.addSong( new Song("Only Girl (In The World)", 235, "Rhianna") );
playlist.addSong( new Song("Thinking of Me", 206, "Olly Murs") );
playlist.addSong( new Song("Raise Your Glass", 202,"P!nk") );
यहां दोनों प्रकार की सॉर्ट विधि के लिए एक कॉल है जो काम करती है, कोई समस्या नहीं:
Collections.sort(playlist1,
Comparator.comparing(p1 -> p1.getTitle()));
playlist1.sort(
Comparator.comparing(p1 -> p1.getTitle()));
जैसे ही मैं श्रृंखला शुरू करता हूं thenComparing, निम्नलिखित होता है:
Collections.sort(playlist1,
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
playlist1.sort(
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
यानी सिंटैक्स त्रुटियां क्योंकि यह p1अब के प्रकार को नहीं जानता है । इसलिए इसे ठीक करने के लिए मैं Songपहले पैरामीटर (तुलना के) में प्रकार जोड़ता हूं :
Collections.sort(playlist1,
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
playlist1.sort(
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
अब यहाँ CONFUSING भाग आता है। पी के लिए laylist1.sort, यानी सूची, यह दोनों thenComparingकॉल के लिए सभी संकलन त्रुटियों को हल करता है। हालाँकि, इसके लिए Collections.sort, यह पहले वाले के लिए हल करता है, लेकिन पिछले एक के लिए नहीं। मैंने परीक्षण में कई अतिरिक्त कॉल जोड़े thenComparingऔर यह हमेशा पिछले एक के लिए एक त्रुटि दिखाता है, जब तक कि मैं (Song p1)पैरामीटर के लिए नहीं डालता ।
अब मैं इसे बनाने TreeSetऔर उपयोग करने के साथ आगे परीक्षण करने के लिए चला गया Objects.compare:
int x = Objects.compare(t1, t2,
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
Set<Song> set = new TreeSet<Song>(
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
के रूप में एक ही बात होती है, के लिए TreeSet, कोई संकलन त्रुटियाँ नहीं हैं, लेकिन Objects.compareअंतिम कॉल के लिए thenComparingएक त्रुटि दिखाती है।
क्या कोई यह बता सकता है कि ऐसा क्यों हो रहा है और यह भी कि (Song p1)जब केवल तुलना विधि (बिना thenComparingकॉल किए) कॉल किया जा रहा है तो इसका उपयोग करने की कोई आवश्यकता क्यों नहीं है ।
एक ही विषय पर एक अन्य प्रश्न है जब मैं यह करने के लिए TreeSet:
Set<Song> set = new TreeSet<Song>(
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
यानी Songतुलना विधि कॉल के लिए पहले लैम्ब्डा पैरामीटर से प्रकार को हटा दें , यह कॉल के तहत सिंटैक्स त्रुटियों को दिखाता है और पहली कॉल करने के लिए thenComparingलेकिन अंतिम कॉल के लिए नहीं thenComparing- ऊपर जो हो रहा था उसके लगभग विपरीत! जबकि, अन्य सभी 3 उदाहरणों के साथ अर्थात Objects.compare, List.sortऔर Collections.sortजब मैं उस पहले Songपरम प्रकार को हटाता हूं तो यह सभी कॉल के लिए सिंटैक्स त्रुटियों को दर्शाता है।
अग्रिम में बहुत धन्यवाद।
एक्लिप्स केपलर SR2 में मुझे मिलने वाली त्रुटियों के स्क्रीनशॉट को शामिल करने के लिए संपादित किया गया था, जो अब मैंने पाया है कि ग्रहण विशिष्ट हैं क्योंकि जब कमांड लाइन पर JDK8 जावा कंपाइलर का उपयोग करके संकलित किया जाता है तो यह ठीक संकलन करता है।
