2015-09-30 15 views
5

List जावा 8 में कक्षा में एक नई विधि sort शामिल है। क्या कोई यह स्पष्ट कर सकता है कि मुझे Collections.sort(..) विधि के विरोध में इसका उपयोग कब करना चाहिए?जावा 8 List.sort उपयोग

उत्तर

3

आपको List.sort के लिए जाना चाहिए।

List.sort का उपयोग कर, तत्वों की लंबाई के संबंध में स्ट्रिंग की एक सूची को सॉर्ट करने का उदाहरण:

List<String> list = new ArrayList<>(Arrays.asList("aa", "aaa", "a")); 
list.sort(comparing(String::length)); 

Collections.sort() ऐसा करने का पूर्व जावा 8 रास्ता नहीं था। ध्यान दें कि दोनों के बीच कोई वास्तविक अंतर नहीं है। आप Collections.sort स्रोत कोड पर एक नज़र डालें, तो आप देख सकते हैं कि यह list.sort कॉल:

public static <T extends Comparable<? super T>> void sort(List<T> list, Comparator<? super T> c) { 
    list.sort(c); 
} 
+0

हाँ, ऐसा लगता 'Collections.sort' JDK1 में' List.sort' को सौंपा जाता है .8। – Unihedron

+4

'संग्रह .ॉर्ट'' की तुलना में 'List.sort' "लैम्ब्डा अभिव्यक्तियों का लाभ उठाने के लिए बेहतर कुछ भी नहीं है। 'List.sort' का लाभ यह है कि 'सूची' कार्यान्वयन इसे ओवरराइड कर सकता है और अधिक कुशल कार्यान्वयन प्रदान करता है, उदा। 'ArrayList' अपने आंतरिक सरणी को सीधे क्रमबद्ध करके डिफ़ॉल्ट कार्यान्वयन के प्रतिलिपि चरण को समाप्त करता है। चूंकि 'Collections.sort' प्रतिनिधियों को' List.sort' पर भेजता है, इससे कोई फर्क नहीं पड़ता कि आप किस विधि का उपयोग करते हैं, आप किसी भी मामले में वह लाभ प्राप्त करेंगे। – Holger

0

आप इसे इस्तेमाल करना चाहिए जब अपने खुद के तुलनित्र प्रदान करते हैं।

list.sort(Comparator.reverseOrder()); 

बजाय:: उदाहरण के लिए

Collections.sort(list); 
Collections.reverse(list); 
+4

आप यह भी लिख सकते हैं: 'संग्रह .sort (सूची, तुलनात्मक.reverseOrder()) '... – assylias

0

सूची वर्ग JSR 335 परिवर्तन के भाग के रूप और हम सूची सॉर्ट करने के लिए है कि विधि का उपयोग कर सकते हैं:

// का उपयोग प्रकार विधि सूची में।

personList.sort ((पी 1, पी 2) -> p1.firstName.compareTo (p2.firstName));

- जावा 8 से पहले हम केवल इस टाई का उपयोग कर सकते हैं --- संग्रह .sort (व्यक्ति सूची, (पी 1, पी 2) -> p1.firstName.compareTo (p2.firstName));

4

कोई कार्यात्मक अंतर नहीं है क्योंकि Collections.sort(list) कॉल list.sort(null) और Collections.sort(list, comparator)list.sort(comparator) पर कॉल करता है।

तो यह सिर्फ शैली का मामला है - जब आप अपना खुद का तुलनित्र प्रदान करते हैं, तो सूची में सॉर्ट करना संभवतः बाहरी स्थैतिक विधि का उपयोग करने से अधिक प्राकृतिक और पठनीय है।

हालांकि यदि आप प्राकृतिक क्रम में सूची को क्रमबद्ध करना चाहते हैं, तो Collections.sort(list)list.sort(null) से अधिक स्पष्ट हो सकता है।

+1

क्या किसी को पता है कि क्यों कोई list.ort()' नहीं है? – user4235730

+3

@ user4235730, 'list.sort()' असुरक्षित है: आप सुरक्षित गैर-तुलनीय सूची और संकलक आपको रोक नहीं पाएंगे। असल में 'list.sort (null)' भी असुरक्षित है, इसलिए इसे 'संग्रह .sort (सूची)' या 'list.sort (तुलनाकर्ता। प्राकृतिक ऑर्डर()) 'का उपयोग करना पसंद है, इसलिए यदि आप गैर की सूची पास करते हैं अतुलनीय तत्वों में आपके पास संकलन त्रुटि होगी। –

3

हालांकि आप List.sort(Comparator) विधि का उपयोग कर सकते हैं, इस विधि का मुख्य उद्देश्य ओवरराइडिंग है। जावा -8 से पहले प्रत्येक List की सॉर्टिंग कुछ हद तक अप्रभावी थी। सबसे पहले सूची को toArray() विधि के माध्यम से सरणी में डाला गया था, फिर सरणी को सॉर्ट किया गया था और अंत में सूची ListIterator.set के माध्यम से अपडेट की गई थी। जावा -8 में यह List.sort(Comparator) डिफ़ॉल्ट विधि में लागू डिफ़ॉल्ट व्यवहार है। हालांकि यदि आप अधिक कुशल एल्गोरिदम प्रदान कर सकते हैं तो आप इसे सबक्लास में बदल सकते हैं। उदाहरण:

  • ArrayList और Arrays.asList(), खुद sort कार्यान्वयन जो सीधे आंतरिक सरणी सॉर्ट करता प्रदान करते हैं, इस प्रकार आप आगे और पीछे की नकल की जरूरत नहीं है।

  • CopyOnWriteArrayList बस अभी सॉर्ट किया जा सकता है!, जावा-7 में

    List<String> list = new CopyOnWriteArrayList<>(Arrays.asList("a", "c", "b")); 
    Collections.sort(list); 
    

    फेंक देता है UnsupportedOperationException क्योंकि समर्थन ListIterator.set इस सूची के विचार (हर इटरेटर स्वतंत्र स्नैपशॉट iterates) के विपरीत है: निम्नलिखित कोड का प्रयास करें। जावा -8 में ListIterator.set अभी भी असमर्थित है, लेकिन यह कोड कस्टम सॉर्ट कार्यान्वयन के कारण सही तरीके से काम करता है।

  • Collections.singletonList और Collections.emptyList बस कुछ नहीं कर (छँटाई 0 या 1 तत्व है नो-सेशन) जो निश्चित रूप से एक एक तत्व या शून्य-तत्व सरणी बनाने की तुलना में तेजी है, तरह यह और सूची पर पुनरावृति मूल्य वापस स्थापित करने के लिए ।

  • Collections.unmodifiableList अब UnsupportedOperationException फेंकता है। जावा -8 से पहले आपको सरणी को अपरिवर्तनीय सूची डंप करने के बाद अपवाद मिला, सरणी को सॉर्ट करना और इसे वापस लिखना शुरू करना।


यहाँ एक उदाहरण है जो उपयोगकर्ता कोड में उपयोगी हो सकता है। मान लीजिए कि आप कुछ सूची की एक मैप किए गए दृश्य बनाना चाहते हैं:

public class MappedList<T, R> extends AbstractList<R> { 
    private final List<T> source; 
    private final Function<? super T, ? extends R> mapper; 

    public MappedList(List<T> source, Function<? super T, ? extends R> mapper) { 
     this.source = source; 
     this.mapper = mapper; 
    } 

    @Override 
    public R get(int index) { 
     return mapper.apply(source.get(index)); 
    } 

    @Override 
    public int size() { 
     return source.size(); 
    } 
} 

उदाहरण उपयोग:

List<String> list = Arrays.asList("a", "foo", "bb", "bar", "qq"); 
List<Integer> mappedList = new MappedList<>(list, String::length); 
System.out.println(mappedList); // prints [1, 3, 2, 3, 2] 

ठीक काम करता है, लेकिन Collections.sort(mappedList); कोशिश कर आप UnsupportedOperationException मिल जाएगा (जैसा कि आप को पलट नहीं सकते set आपरेशन काम नहीं करता है मैपिंग फ़ंक्शन)। लेकिन यदि आप MappedList में sort() तरीका लागू है, तो आप (मूल सूची को बदलने) इसे सही ढंग से सुलझाने के लिए सक्षम हो जाएगा:

@Override 
public void sort(Comparator<? super R> c) { 
    @SuppressWarnings("unchecked") 
    Comparator<? super T> comparator = c == null ? 
     Comparator.comparing((Function<? super T, ? extends Comparable<Object>>) mapper) : 
     Comparator.comparing(mapper, c); 
    source.sort(comparator); 
} 

List<String> list = Arrays.asList("a", "foo", "bb", "bar", "qq"); 
List<Integer> mappedList = new MappedList<>(list, String::length); 
Collections.sort(mappedList); 
System.out.println(mappedList); // prints [1, 2, 2, 3, 3] 
System.out.println(list); // prints [a, bb, qq, foo, bar]