2012-04-27 12 views
19

मेरे पास एक अपरिवर्तनीय सेट है (Set<Integer> के रूप में डाला गया) जिसमें संभावित रूप से कई तत्व शामिल हैं। मुझे एक संग्रह की आवश्यकता है जिसमें उस सेट के तत्व और एक अतिरिक्त तत्व शामिल हो। मेरे पास सेट की प्रतिलिपि बनाने के लिए जगह में कोड है, फिर तत्व को संलग्न करें, लेकिन मैं सही रास्ता ढूंढ रहा हूं जो चीजों को यथासंभव कुशल रखता है।एक अपरिवर्तनीय सेट में एक तत्व जोड़ने के लिए एक कुशल और सुरुचिपूर्ण तरीका क्या है?

मेरे पास गुवा उपलब्ध है, हालांकि मुझे इसके उपयोग की आवश्यकता नहीं है।

उत्तर

28

प्रदर्शन के बारे में सुनिश्चित नहीं हैं, लेकिन आप का उपयोग अमरूद के ImmutableSet.Builder कर सकते हैं:

public static <T> Set<T> setWith(Set<T> old, T item) { 
    return new ImmutableSet.Builder<T>().addAll(old).add(item).build(); 
} 

// ... 
Set<Integer> newSet = setWith(oldSet, 3); 
3

यदि सेट अपरिवर्तनीय है, तो मुझे सेट कॉपी करने के अलावा इसे करने का कोई तरीका नहीं दिखता है, और फिर अपना नया तत्व जोड़ें। याद रखें, एक सेट कॉपी करना नया सेट बनाते समय कन्स्ट्रक्टर फ़ंक्शन पर बेस सेट पास करने जितना आसान है।

+0

मुझे लगता है कि यह निहित है; सवाल यह लागू करने के लिए _how_ के बारे में है। – sdgfsdh

2

जब मैं "अपरिवर्तनीय" और "जोड़ना" पढ़ता हूं तो मुझे संज्ञानात्मक विसंगति का सामना करना पड़ रहा है। आप अपरिवर्तनीय मानों की एक परिवर्तनीय प्रति के अंत में एक नया तत्व जोड़ सकते हैं, लेकिन आप अपरिवर्तनीय सेट को संशोधित नहीं कर सकते हैं। मुझे कुछ भी सुरुचिपूर्ण नहीं पता है।

3

आप तीन विकल्प हैं:

import com.google.common.collect.ImmutableSet 

// ... 
Set<Integer> newSet = new ImmutableSet.Builder<Integer>() 
           .addAll(oldSet) 
           .add(3) 
           .build(); 

बेशक आप भी अपने आप उस के लिए एक सहायक विधि लिख सकते हैं।

  • एक परिवर्तनीय सेट का उपयोग करें।
  • जांचें कि तत्व पहले से मौजूद नहीं है, अगर सेट की एक प्रति नहीं बनाते हैं और कोई तत्व जोड़ते हैं।
  • एक रैपर सेट बनाएं जिसमें पिछले सेट और तत्व शामिल है।

कभी कभी एक BitSet अपने मूल्यों के वितरण पर निर्भर करता है Set<Integer> तुलना में एक बेहतर विकल्प है।

+0

एक म्यूटेबल सेट का उपयोग नहीं कर सकता - मैं एपीआई को नियंत्रित नहीं करता जो मान देता है। यह जांचना कि यह मौजूद नहीं है, निश्चित रूप से अच्छी सलाह है। धन्यवाद। – Max

+0

चेक की प्रतिलिपि की तुलना में चेक की तुलना में त्वरित है। –

+0

क्या निर्माता यह जांच नहीं करेगा कि यह पहले से ही मौजूद है या नहीं? मेरा मतलब है एक प्रति आवंटित करने से पहले। – jmg

3

आप Sets.union() पर विचार कर सकते हैं। निर्माण तेजी से होगा, लेकिन धीमी गति से उपयोग करें।

public static <T> Set<T> setWith(Set<T> old, T item) { 
    return Sets.union(old, Collections.singleton(item); 
} 

(com.google.common.collect.Sets & java.util.Collections)

0

आप एक पूरी कॉपी की तुलना में बेहतर प्रदर्शन चाहते हैं, और आप तत्वों पर एक आदेश है, तो आप एक का उपयोग कर सकते अच्छा वृद्धिशील सेट प्रदर्शन प्राप्त करने के लिए B+ tree के आसपास प्रभावी रूप से अपरिवर्तनीय रैपर।

बी + पेड़ में कोई आइटम जोड़ने के लिए ओ (लॉग (एन)) समय और वृद्धिशील आवंटन की आवश्यकता होती है, ओ (एन) नहीं, जैसा कि आप ImmutableSet.builder().addAll(...).add(...).build() के साथ प्राप्त करते हैं। इसका मतलब है कि एन वृद्धिशील जोड़ों से एक सेट बनाना ओ (एन * लॉग (एन)) है, ओ नहीं (वर्ग (एन))।

यह answer में जेडीबीएम लाइब्रेरी के लिए एक पॉइंटर है, इसलिए यह jdbm:jdbm पर देखने लायक हो सकता है।

संबंधित मुद्दे