नई सूची बनाए बिना सेट सूची में कनवर्ट करें


503

मैं एक कन्वर्ट करने के लिए इस कोड का उपयोग कर रहा Setएक करने के लिए List:

Map<String, List<String>> mainMap = new HashMap<>();

for (int i=0; i < something.size(); i++) {
  Set<String> set = getSet(...); //returns different result each time
  List<String> listOfNames = new ArrayList<>(set);
  mainMap.put(differentKeyName, listOfNames);
}

मैं लूप के प्रत्येक पुनरावृत्ति में एक नई सूची बनाने से बचना चाहता हूं। क्या यह संभव है?


1
मुझे पता है कि सेट करने के लिए सेट करने के लिए क्यू के रूप में परिवर्तित करने का एक तरीका है। मैं लूप में हर बार नई सूची बनाना चाहता हूं।
मुहम्मद इमरान तारिक

4
आप केवल सेट को मुख्य सूची में क्यों नहीं जोड़ सकते? आपको सेट को सूची में बदलने की आवश्यकता क्यों है?
DagR

1
क्या सूची बनाने की आपकी मंशा है <List <?? >>
Hiery Nomus

5
आप नहीं कर सकते। आपका प्रश्न शब्दों में विरोधाभास का प्रतीक है।
लोर्ने

जवाबों:


802

आप List.addAll () विधि का उपयोग कर सकते हैं । यह एक संग्रह को एक तर्क के रूप में स्वीकार करता है, और आपका सेट एक संग्रह है।

List<String> mainList = new ArrayList<String>();
mainList.addAll(set);

संपादित करें: सवाल के संपादन के जवाब के रूप में।
यह देखना आसान है कि यदि आप के रूप में मानों के Mapसाथ एक होना चाहते Listहैं, तो विभिन्न मूल्यों के क्रम में, आपको विभिन्न सूचियों को बनाने की आवश्यकता है।
इस प्रकार: आप इन सूचियों को बनाने से बच नहीं सकते हैं, सूचियों को बनाना होगा।

आसपास संभव कार्य:
अपने या Mapएक के रूप में घोषणा करें , और बस अपना सेट डालें।Map<String,Set>Map<String,Collection>


1
क्षमा करें, यह मुख्य सूची नहीं थी। प्रश्न देखें
मुहम्मद इमरान तारिक

@imrantariq: differentKeyNameहर बदलाव बदल रहा है? क्या आप वास्तव something.size()में अपने नक्शे में विभिन्न संभावित मूल्यों को चाहते हैं ? यह देखना आसान है कि kसूचियों के साथ एक मानचित्र जैसा कि मूल्यों को कम से कम kसूचियां बनाने की आवश्यकता है ।
अमित

@imrantariq: और आप मान लें कि प्रत्येक कुंजी के लिए एक अलग सूची चाहिए?
अमित

@imrantariq: आप जो अनुरोध कर रहे हैं वह असंभव है। अधिक विवरण के लिए मेरा संपादन पढ़ें।
अमित

यह NullPointerException को लौटा देगा केस सेट में अशक्त है।
w35l3y

411

इसे बदलने के लिए कंस्ट्रक्टर का उपयोग करें:

List<?> list = new ArrayList<?>(set);

21
उन्होंने विशेष रूप से कहा कि वह इससे बचना चाहते हैं।
मानचित्रकार

3
@ इरुकलेवैंट, क्योंकि उनकी आवश्यकता कार्यान्वयन योग्य नहीं है।
लोर्न जू के मार्किस

16
@ ईजेपी को उसके जवाब में यह कहने की ज़रूरत है कि, ओपी ने केवल यह बताने के बजाय कि कोई स्पष्टीकरण नहीं दिया है।
मानचित्रकार

वह इसे टाल रहा है, कि कंस्ट्रक्टर System.arrayCopy का उपयोग करता है, जो उथली प्रतियां बनाता है, जिसका अर्थ है, यह केवल ऑब्जेक्ट के संदर्भ को उस सरणी में कॉपी करता है जिसका उपयोग सूची बनाने के लिए किया जाता है। यदि आप दोनों संग्रहों की तुलना करते हैं, तो आप देखेंगे कि उन दोनों में समान वस्तुओं के संदर्भ हैं।
गोबट्रॉन

यह वास्तव में Android पर काम नहीं करता है। कोई भी कारण क्यों?
kbluue

84

अमरूद कलेक्ट लाइब्रेरी से भी, आप उपयोग कर सकते हैं newArrayList(Collection):

Lists.newArrayList([your_set])

यह एमिट के पिछले उत्तर के समान होगा , सिवाय इसके कि आपको किसी listवस्तु को घोषित (या इंस्टेंटेट) करने की आवश्यकता नहीं है ।


1
यदि आप अमरूद का उपयोग कर रहे हैं, तो यह आसान है
vsingh

6
हालाँकि आप सीधे कंस्ट्रक्टर को कॉल नहीं कर रहे हैं, फिर भी यह विधि ArrayListकंस्ट्रक्टर को कॉल करती है ।
glen3b

अगर मैं सूची की घोषणा नहीं करता हूं, तो मैं बनाई गई सूची का उपयोग कैसे कर सकता हूं?
कोरे तुगे

@KorayTugay, अच्छी तरह से आप Lists.newArrayList ([your_set]) को एक चर (स्थानीय या वैश्विक) में निकालते हैं । जैसे: सूची <Foo> fooList = Lists.newArrayList (setOfFoo) लेकिन आपका प्रश्न त्रुटिपूर्ण है। यदि आप एक सूची बनाते हैं तो यह कम से कम अंतर्निहित रूप से घोषित किया जाता है (यदि स्पष्ट रूप से नहीं)।
चय्याचैय्या

1
किसी भी अनुमान के रूप में क्यों इस विधि बनाया? यह किसी से बेहतर नहीं लगता है new ArrayList<>([your_set])
डेविड एफएस

49

हम जावा 8 में एक लाइनर का उपयोग कर सकते हैं:

List<String> list = set.stream().collect(Collectors.toList());

यहाँ एक छोटा सा उदाहरण है:

public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("A");
        set.add("B");
        set.add("C");
        List<String> list = set.stream().collect(Collectors.toList());
}

7
पठनीयता के लिए यह अनुशंसित नहीं है। उदाहरण के लिए, IntelliJ "नया ArrayList <> (सेट)" का सुझाव देता है और 20 से अधिक समान कोड नमूनों को सूचीबद्ध करता है जिन्हें उसी तरह से प्रतिस्थापित किया जा सकता है।
rrhrg

बिल्कुल सही! @rrgg जो प्रदर्शन के लिए बेहतर है यदि हम set.parallelStream () का उपयोग करते हैं?
गौरव

31

सबसे सरल उपाय

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

 return new ArrayList<Long>(mySetVariable);

1
यह भी वही है जो इंटेलीज आईडीईए धाराओं एपीआई के बजाय सुझाता है।
बेन

6

आप इस एक पंक्ति परिवर्तन का उपयोग कर सकते हैं: Arrays.asList(set.toArray(new Object[set.size()]))

Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); 
  mainMap.put(differentKeyName, Arrays.asList(set.toArray(new Object[set.size()])));
}  

सही आकार क्योंकि नई वस्तु [0] केवल एक तत्व को धारण करेगी लेकिन नई वस्तु [set.size ()] सभी मानों को बनाए
रखेगी

5

मुझे क्या करना होगा :

Map<String, Collection> mainMap = new HashMap<String, Collection>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //return different result each time
  mainMap.put(differentKeyName,set);
}

5

चूंकि यह अब तक उल्लेख नहीं किया गया है, जावा 10 के रूप में आप नई copyOfफैक्टरी विधि का उपयोग कर सकते हैं :

List.copyOf(set);

से जावाडोक :

दिए गए संग्रह के तत्वों से युक्त एक अनम्य सूची देता है , अपने पुनरावृति क्रम में।


3

जावा 8 स्ट्रीम का उपयोग करने का विकल्प प्रदान करता है और आप निम्न से एक सूची प्राप्त कर सकते हैं Set<String> setString:

List<String> stringList = setString.stream().collect(Collectors.toList());

हालांकि आंतरिक कार्यान्वयन अब एक उदाहरण प्रदान करता है ArrayList:

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

लेकिन JDK इसकी गारंटी नहीं देता है। जैसा कि यहां बताया गया है :

लौटाए गए सूची के प्रकार, परिवर्तनशीलता, क्रमबद्धता या थ्रेड-सुरक्षा पर कोई गारंटी नहीं है; यदि लौटी हुई सूची पर अधिक नियंत्रण की आवश्यकता है, तोCollection (आपूर्तिकर्ता) का उपयोग करें।

यदि आप हमेशा सुनिश्चित करना चाहते हैं तो आप उदाहरण के लिए विशेष रूप से अनुरोध कर सकते हैं:

List<String> stringArrayList = setString.stream()
                     .collect(Collectors.toCollection(ArrayList::new));

2

मैं सरल staticविधि बनाता हूं :

public static <U> List<U> convertSetToList(Set<U> set)
{
    return new ArrayList<U>(set);
}

... या यदि आप सूची का प्रकार सेट करना चाहते हैं, जिसका आप उपयोग कर सकते हैं:

public static <U, L extends List<U>> List<U> convertSetToList(Set<U> set, Class<L> clazz) throws InstantiationException, IllegalAccessException
{
    L list = clazz.newInstance();
    list.addAll(set);
    return list;
}

2

हाल ही में मैंने यह पाया:

ArrayList<T> yourList = Collections.list(Collections.enumeration(yourSet<T>));

1
क्या आप इसका विस्तार या विस्तार कर सकते हैं?
वंदाल

कलेक्शंस.लिस्ट () एक नया ArrayList बनाता है:public static <T> ArrayList<T> list(Enumeration<T> e) { ArrayList<T> l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); return l; }
Artem Lukanin

2

परिपूर्णता के लिए...

कि आप कहते हैं कि वास्तव में क्या कर इलाज के लिए चाहते हैं Mapके रूप में मान Listहै, लेकिन आप को कॉपी से बचना चाहते हैं Setएक में Listहर बार।

उदाहरण के लिए, हो सकता है कि आप एक लाइब्रेरी फ़ंक्शन को कॉल कर रहे हैं जो एक बनाता है Set, लेकिन आप अपना Map<String, List<String>>परिणाम एक (खराब-डिज़ाइन किए गए लेकिन अपने हाथों से) लाइब्रेरी फ़ंक्शन को पारित कर रहे हैं Map<String, List<String>>, जो केवल लेता है , भले ही किसी भी तरह आपको पता हो कि ऑपरेशन इसके साथ करता है Lists किसी भी Collection(और इस प्रकार किसी भी Set) के लिए समान रूप से लागू होते हैं । और किसी कारण से आपको प्रत्येक सेट को एक सूची में कॉपी करने की गति / मेमोरी ओवरहेड से बचने की आवश्यकता होती है।

इस सुपर आला मामले में, (शायद अनजाने में) व्यवहार के आधार पर लाइब्रेरी फ़ंक्शन को आपके Lists से बाहर की जरूरत है , आप प्रत्येक सेट पर एक List दृश्य बनाने में सक्षम हो सकते हैं । ध्यान दें कि यह स्वाभाविक रूप से असुरक्षित है (क्योंकि प्रत्येक से लाइब्रेरी फ़ंक्शन की आवश्यकताओं Listको संभवतः आप बिना जाने बदल सकते हैं), इसलिए एक और समाधान को प्राथमिकता दी जानी चाहिए। लेकिन यहाँ आप इसे कैसे करेंगे।

आप एक ऐसी क्लास बनाएँगे जो Listइंटरफ़ेस को लागू करती है, Setकंस्ट्रक्टर में ले जाती है और उस सेट को एक फील्ड में असाइन करती है, और फिर एपीआई Setको लागू करने के लिए उस आंतरिक का उपयोग करती Listहै (हद तक, और वांछित)।

ध्यान दें कि कुछ सूची व्यवहार आप केवल तत्वों के रूप में संग्रहीत किए बिना नकल करने में सक्षम नहीं होंगे List, और कुछ व्यवहार आप केवल आंशिक रूप से नकल करने में सक्षम होंगे। फिर, यह वर्ग Listसामान्य रूप से s के लिए एक सुरक्षित ड्रॉप-इन प्रतिस्थापन नहीं है । विशेष रूप से, यदि आप जानते हैं कि उपयोग के मामले में अनुक्रमणिका से संबंधित संचालन की आवश्यकता होती है या MUTATING List, यह दृष्टिकोण बहुत तेजी से दक्षिण की ओर जाएगा।

public class ListViewOfSet<U> implements List<U> {
    private final Set<U> wrappedSet;
    public ListViewOfSet(Set<U> setToWrap) { this.wrappedSet = setToWrap; }

    @Override public int size() { return this.wrappedSet.size(); }
    @Override public boolean isEmpty() { return this.wrappedSet.isEmpty(); }
    @Override public boolean contains(Object o) { return this.wrappedSet.contains(o); }
    @Override public java.util.Iterator<U> iterator() { return this.wrappedSet.iterator(); }
    @Override public Object[] toArray() { return this.wrappedSet.toArray(); }
    @Override public <T> T[] toArray(T[] ts) { return this.wrappedSet.toArray(ts); }
    @Override public boolean add(U e) { return this.wrappedSet.add(e); }
    @Override public boolean remove(Object o) { return this.wrappedSet.remove(o); }
    @Override public boolean containsAll(Collection<?> clctn) { return this.wrappedSet.containsAll(clctn); }
    @Override public boolean addAll(Collection<? extends U> clctn) { return this.wrappedSet.addAll(clctn); }
    @Override public boolean addAll(int i, Collection<? extends U> clctn) { throw new UnsupportedOperationException(); }
    @Override public boolean removeAll(Collection<?> clctn) { return this.wrappedSet.removeAll(clctn); }
    @Override public boolean retainAll(Collection<?> clctn) { return this.wrappedSet.retainAll(clctn); }
    @Override public void clear() { this.wrappedSet.clear(); }
    @Override public U get(int i) { throw new UnsupportedOperationException(); }
    @Override public U set(int i, U e) { throw new UnsupportedOperationException(); }
    @Override public void add(int i, U e) { throw new UnsupportedOperationException(); }
    @Override public U remove(int i) { throw new UnsupportedOperationException(); }
    @Override public int indexOf(Object o) { throw new UnsupportedOperationException(); }
    @Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException(); }
    @Override public ListIterator<U> listIterator() { throw new UnsupportedOperationException(); }
    @Override public ListIterator<U> listIterator(int i) { throw new UnsupportedOperationException(); }
    @Override public List<U> subList(int i, int i1) { throw new UnsupportedOperationException(); }
}

...
Set<String> set = getSet(...);
ListViewOfSet<String> listOfNames = new ListViewOfSet<>(set);
...

यह वास्तव में एकमात्र उत्तर है जो वास्तव में प्रश्न में वर्णित समस्या को हल करता है!
Lii

आप इस बहुत आसानी से AbstractList
Lii

1

मुझे यह एक सेट से सूची बनाने के लिए ठीक और उपयोगी लगा।

ArrayList < String > L1 = new ArrayList < String > ();
L1.addAll(ActualMap.keySet());
for (String x: L1) {
    System.out.println(x.toString());
}

-15
Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //return different result each time
  mainMap.put(differentKeyName, new ArrayList(set));
}

11
आपने सूची बनाने से परहेज नहीं किया है। यह कोड तुच्छ रूप से आपके प्रश्न के नमूने के समान है।
टेलर

2
लेकिन यह आपके प्रश्न का उत्तर नहीं देता है, ऐसा नहीं है कि एक उत्तर है।
लोर्न जू के मार्किस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.