मैं विशेष रूप से स्थैतिक तरीकों का उपयोग करने के बारे में 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 जावा कंपाइलर का उपयोग करके संकलित किया जाता है तो यह ठीक संकलन करता है।