नकल जावा सेट करता है


83

क्या नकल करने का कोई तरीका है TreeSet? यही है, क्या यह संभव है

Set <Item> itemList;
Set <Item> tempList;

tempList = itemList;

या क्या आपको सेट के माध्यम से शारीरिक रूप से पुनरावृत्त करना है और उन्हें एक-एक करके कॉपी करना है?


8
tempList.addAll(itemList)
ढबला

जवाबों:


156

ऐसा करने का एक और तरीका है कॉपी कंस्ट्रक्टर का उपयोग करना :

Collection<E> oldSet = ...
TreeSet<E> newSet = new TreeSet<E>(oldSet);

या एक खाली सेट बनाएं और तत्वों को जोड़ें:

Collection<E> oldSet = ...
TreeSet<E> newSet = new TreeSet<E>();
newSet.addAll(oldSet);

cloneइन के विपरीत आप एक अलग सेट वर्ग, एक अलग तुलनित्र, या यहां तक ​​कि कुछ अन्य (गैर-सेट) संग्रह प्रकार से आबाद करने की अनुमति देते हैं।


ध्यान दें कि कॉपी करने का नतीजा उन वस्तुओं के संदर्भ Setमें एक नया है Setजो मूल हैं तो तत्व हैं Set। तत्व ऑब्जेक्ट स्वयं कॉपी या क्लोन नहीं किए जाते हैं। यह जावा Collectionएपीआई को काम करने के लिए डिज़ाइन किए गए तरीके से अनुरूप है : वे तत्व वस्तुओं की नकल नहीं करते हैं।


7

जावा 8 के साथ आप उपयोग कर सकते हैं streamऔर collectवस्तुओं की नकल कर सकते हैं :

Set<Item> newSet = oldSet.stream().collect(Collectors.toSet());

या आप एक को जमा कर सकते हैं ImmutableSet(यदि आप जानते हैं कि सेट को बदलना नहीं चाहिए):

Set<Item> newSet = oldSet.stream().collect(ImmutableSet.toImmutableSet());

8
आप कर सकते हैं ... लेकिन कॉपी कंस्ट्रक्टर (आदि) को और अधिक कुशल होना चाहिए यदि आप बस एक संग्रह की नकल कर रहे हैं।
स्टीफन सी

3

@Stephen C द्वारा दिया गया कॉपी कंस्ट्रक्टर आपके द्वारा Setबनाए गए (या जब आप जानते हैं कि यह कहां से आता है) जाने का रास्ता है । जब यह एक से आता है Map.entrySet(), तो यह Mapआपके द्वारा उपयोग किए जा रहे कार्यान्वयन पर निर्भर करेगा :

खोजबग कहता है

एंट्रीसेट () पद्धति को अंतर्निहित मानचित्र का एक दृश्य वापस करने की अनुमति है जिसमें पुनरावृत्ति के दौरान एक एकल प्रविष्टि ऑब्जेक्ट का पुन: उपयोग और वापस किया जाता है। जावा 1.6 के रूप में, IdentityHashMap और EnumMap दोनों ने ऐसा किया। इस तरह के मानचित्र के माध्यम से पुनरावृत्ति करते समय, प्रविष्टि मूल्य केवल तब तक मान्य होता है जब तक आप अगले पुनरावृत्ति के लिए आगे नहीं बढ़ जाते हैं। यदि, उदाहरण के लिए, आप इस तरह के एंट्रीसेट को एक ऐडऑल विधि से पास करने की कोशिश करते हैं, तो चीजें बुरी तरह से गलत हो जाएंगी।

जैसा addAll() कि कॉपी कंस्ट्रक्टर द्वारा कहा जाता है, आप अपने आप को केवल एक एंट्री के सेट के साथ पा सकते हैं: आखिरी।

Mapहालांकि सभी कार्यान्वयन ऐसा नहीं करते हैं, इसलिए यदि आप जानते हैं कि आपका कार्यान्वयन उस संबंध में सुरक्षित है, तो कॉपी निर्माता निश्चित रूप से जाने का रास्ता है। अन्यथा, आपको Entryस्वयं नई वस्तुएं बनानी होंगी:

Set<K,V> copy = new HashSet<K,V>(map.size());
for (Entry<K,V> e : map.entrySet())
    copy.add(new java.util.AbstractMap.SimpleEntry<K,V>(e));

संपादित करें: जावा 7 और जावा 6u45 (स्टीफन सी के लिए धन्यवाद) पर किए गए परीक्षणों के विपरीत, खोजबीन टिप्पणी अब उपयुक्त नहीं लगती है। यह शायद जावा 6 (यू 45 से पहले) के पुराने संस्करणों पर हो सकता है लेकिन मेरे पास परीक्षण करने के लिए नहीं है।


1
क्या यह अवलोकन पर आधारित है? यदि हां, तो यह addAllकार्यान्वयन में बग की तरह लगता है । एफडब्ल्यूआईडब्ल्यू, Mapकार्यान्वयन मैंने सभी एंट्री सेट (कुछ स्तर पर) को देखा है, और प्रत्येक के लिए कुंजी और मान निकालें । तथ्य यह है कि एंट्री सेट इटरेटर एक ही वस्तु को लौटा सकता है जो प्रत्येक के लिए समय नहीं है। एकमात्र मामला जो मैंने देखा वह अलग था EnumMapजहां कॉपी कंस्ट्रक्टर खुद प्रविष्टियों को क्लोन कर रहा था ... अगर स्रोत का नक्शा एक था EnumMap
स्टीफन सी।

1
@StephenC ऐसा लगता है कि आप सही हैं: मैंने जो परीक्षण किए IdentityHashMapहैं, वे उस बग की ओर नहीं ले जाते हैं। अधिक परेशान यह है कि मैंने इसे जावा 6u45 पर परीक्षण किया और कोई समस्या भी नहीं थी। मुझे लगता है कि यह खोज में बग (या JDK वे अपने नियमों को ...) पर आधारित है। मैं अपना उत्तर संपादित करूँगा।
Matthieu

3

जावा 10 से शुरू :

Set<E> oldSet = Set.of();
Set<E> newSet = Set.copyOf(oldSet);

Set.copyOf()Setदिए गए तत्वों से युक्त एक अपरिवर्तनीय रिटर्न देता हैCollection

दिए गए Collectionनहीं होना चाहिए null, और इसमें कोई nullतत्व नहीं होना चाहिए ।


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