एक संग्रह को सूची में कैसे बदलें?


294

मैं अपाचे कलेक्शंस लाइब्रेरी TreeBidiMapसे उपयोग कर रहा हूं । मैं इसे उन मूल्यों पर क्रमबद्ध करना चाहता हूं जो हैं ।doubles

मेरी विधि का Collectionउपयोग कर मूल्यों को प्राप्त करने के लिए है:

Collection coll = themap.values();

जो स्वाभाविक रूप से ठीक काम करता है।

मुख्य प्रश्न: मैं अब पता करने के लिए मैं / डाली (नहीं यकीन है कि जो सही है) कैसे परिवर्तित कर सकते हैं चाहते हैं collएक में Listतो यह हल हो सकता है?

मैं तब सॉर्ट किए गए Listऑब्जेक्ट पर पुनरावृति करने का इरादा रखता हूं , जो क्रम में होना चाहिए और जहां TreeBidiMap( जहां themap) themap.getKey(iterator.next())इट्रेटर की सूची से अधिक होगा का उपयोग करके उपयुक्त कुंजियों को प्राप्त करना चाहिए doubles


4
आप किसी प्रकार के SortedMap का उपयोग करके सीधे इस चरण से बचना चाह सकते हैं, इसलिए प्रविष्टियां कुंजी के प्राकृतिक क्रम में उपयोग की जा रही हैं। Java का खुद का TreeMap SortedMap औजार।
Axel Knauf

TreeBidiMapएक OrderedMap, आदेश ठीक होना चाहिए। प्रश्न में छँटाई आवश्यक मानों पर है, कुंजियों पर नहीं।
वलसेक

जवाबों:


470
List list = new ArrayList(coll);
Collections.sort(list);

जैसा कि एरेल सेगल हलेवी नीचे कहते हैं, यदि टक पहले से ही एक सूची है, तो आप चरण एक को छोड़ सकते हैं। लेकिन यह TreeBidiMap के आंतरिक पर निर्भर करेगा।

List list;
if (coll instanceof List)
  list = (List)coll;
else
  list = new ArrayList(coll);

4
बस ध्यान दें कि दो दृष्टिकोणों के अलग-अलग दुष्प्रभाव हैं: संग्रह को एक सूची में डालना और फिर छंटाई भी मूल संग्रह को छाँटेगी; प्रति बनाने से नहीं होगा।
बार्नी

यदि बार-बार उपयोग किया जाता है तो यह दृष्टिकोण प्रदर्शन को बहुत कम कर देता है। एक समाधान के लिए मेरा जवाब देखें जो काम करता है-पर-मक्खी, इसमें एक कस्टम संग्रह शामिल है।
वलसेक

यह मामला हल नहीं करता है जब map.values ​​() "आंतरिक वर्ग" संग्रह लौटाता है। संकलक रिपोर्ट करता है कि Collections.sort (सूची <T>) Collections.sort (सूची <InnerClass>) को स्वीकार नहीं करता है। समाधान भी उपयोग करने के लिए था: सूची <इनरक्लास> सूची = map.values ​​()। स्ट्रीम ()। कलेक्टर्स (कलेक्टर्स.लॉलिस्ट ())
परेरा


33

मुझे लगता है कि पॉल टोंबलिन का जवाब बेकार हो सकता है अगर मामला पहले से ही एक सूची है, क्योंकि यह एक नई सूची बनाएगा और सभी तत्वों की नकल करेगा। यदि टक में कई हाथी होते हैं, तो इसमें लंबा समय लग सकता है।

मेरा सुझाव है:

List list;
if (coll instanceof List)
  list = (List)coll;
else
  list = new ArrayList(coll);
Collections.sort(list);

21

मुझे विश्वास है कि आप इसे इस प्रकार लिख सकते हैं:

coll.stream().collect(Collectors.toList())

कास्टिंग करने के लिए बेहतर तरीका
Stackee007

महान! इससे मेरा मामला सुलझ गया। मेरा map.values ​​() "आंतरिक वर्ग" संग्रह लौटाता है। कंपाइलर ने बताया कि कलेक्शंस.सोर्ट (लिस्ट <टी>) कलेक्शंस.सॉर्ट (लिस्ट <इनरक्लास>) को स्वीकार नहीं करता है।
परेरा

Android में मेरे उपयोग-मामले के लिए काम नहीं किया। न्यूनतम एपी 24 की आवश्यकता है
एश सच्देवा

8
Collections.sort( new ArrayList( coll ) );

ArrayList का उपयोग करने के लिए एक संदर्भ गुम है?
ज़च स्क्रिपवेन

@Zach: mmhh अच्छी बात। मुझे पता था कि मेरे लिए सीडब्ल्यू के रूप में इसे चिह्नित करने का एक कारण था। BTW पॉल ans एक है। मुझे नहीं पता कि उसके पास केवल मेरे यूवी क्यों हैं।
OscarRyz

4

@ कुनिगामी: मुझे लगता है कि आप अमरूद की newArrayListविधि के बारे में गलत हो सकते हैं । यह जाँच नहीं करता है कि क्या Iterable एक सूची प्रकार है और बस दी गई सूची को वापस-जैसा है। यह हमेशा एक नई सूची बनाता है:

@GwtCompatible(serializable = true)
public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
  checkNotNull(elements); // for GWT
  // Let ArrayList's sizing logic work, if possible
  return (elements instanceof Collection)
      ? new ArrayList<E>(Collections2.cast(elements))
      : newArrayList(elements.iterator());
}

यह कैसे अधिक मतदान नहीं है? कुनिगामी का उत्तर गलत है (जहाँ तक यह अंतर्निहित कार्यान्वयन के बारे में माना जाता है)।
ग्रीनमीनी

0

आप जो अनुरोध करते हैं वह काफी महंगा ऑपरेशन है, सुनिश्चित करें कि आपको इसे अक्सर करने की आवश्यकता नहीं है (उदाहरण के लिए एक चक्र में)।

अन्यथा, आप एक कस्टम संग्रह बना सकते हैं। मैं आपके साथ TreeBidiMapऔर TreeMultisetहुड के नीचे एक के साथ आया था । केवल उसी चीज़ को लागू करें जो आपको आवश्यक है और डेटा अखंडता के बारे में परवाह है।

class MyCustomCollection implements Map<K, V> {
    TreeBidiMap<K, V> map;
    TreeMultiset<V> multiset;
    public V put(K key, V value) {
        removeValue(map.put(key, value));
        multiset.add(value);
    }
    public boolean remove(K key) {
        removeValue(map.remove(key));
    }
    /** removes value that was removed/replaced in map */
    private removeValue(V value) {
        if (value != null) {
            multiset.remove(value);
        }
    }
    public Set keySet() {
        return map.keySet();
    }
    public Multiset values() {
        return multiset;
    }
    // many more methods to be implemented, e.g. count, isEmpty etc.
}

इस तरह, आपके पास से सॉर्ट Multiset किया गया है values()। हालाँकि, यदि आपको इसकी सूची बनाने की आवश्यकता है (जैसे आपको सरणी जैसी get(index)विधि की आवश्यकता है ), तो आपको कुछ और जटिल चीज़ों का आविष्कार करना होगा।


keySet()और values()मूल में दृश्य हैं Map, इसलिए जब उन्हें संशोधित किया जाता है तो बैकिंग Mapको भी संशोधित करने की आवश्यकता होती है, आपका समाधान इस बात का समर्थन नहीं करता है
लिनो

-4

यहाँ एक लाइनर के रूप में एक उप-इष्टतम समाधान है:

Collections.list(Collections.enumeration(coll));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.