Java में Array को Set में कैसे बदलें


717

मैं एक सरणी को जावा में सेट में बदलना चाहूंगा। ऐसा करने के कुछ स्पष्ट तरीके हैं (जैसे कि एक लूप के साथ), लेकिन मैं थोड़ा सा कुछ पसंद करूंगा, कुछ इस तरह:

java.util.Arrays.asList(Object[] a);

कोई विचार?

जवाबों:


1226

ऐशे ही:

Set<T> mySet = new HashSet<>(Arrays.asList(someArray));

जावा 9+ में, यदि अचूक सेट ठीक है:

Set<T> mySet = Set.of(someArray);

जावा 10+ में, सामान्य प्रकार पैरामीटर को सरणियों घटक प्रकार से अनुमान लगाया जा सकता है:

var mySet = Set.of(someArray);

10
मैं अंतिम <T> छोड़ दूंगा, अन्यथा अच्छा ऑनलाइनर!
despot

165
@ दत्ताज: गलत; Arrays.asListO (1) है।
SLKs

67
ध्यान दें कि यदि आप इस पद्धति का उपयोग आदिमों की एक सरणी पर करते हैं जैसे कि int [] यह एक सूची लौटाएगा <int []> ताकि आप इच्छित व्यवहार प्राप्त करने के लिए रैपर कक्षाओं का उपयोग करें।
टी। मार्कले

6
@ अजयगोतम: यह केवल अमरूद में है।
एसएलके

10
: मैं पठनीयता दक्षता से अधिक (लगभग) हर बार ले लेंगे blog.codinghorror.com/...
डेविड Carboni

221
Set<T> mySet = new HashSet<T>();
Collections.addAll(mySet, myArray);

कि JDK 6 से संग्रह .addAll (java.util.Collection, T ...) है।

इसके अतिरिक्त: क्या होगा यदि हमारी सरणी प्राइमेट से भरी हुई है?

JDK <8 के लिए, मैं केवल एक ही forपास में रैप और ऐड-टू-सेट करने के लिए स्पष्ट लूप लिखूंगा ।

JDK> = 8 के लिए, एक आकर्षक विकल्प कुछ इस प्रकार है:

Arrays.stream(intArray).boxed().collect(Collectors.toSet());

5
आप ऐसा कर सकते हैं java.util.Collections.addAll। इसके अलावा, मैं अब कॉमन्स कलेक्शंस की सिफारिश नहीं करूंगा, इसके साथ क्या उत्पन्न नहीं हो रहा है और अमरूद मौजूदा है।
कोलिनड

14
SL SLs के उत्तर की तुलना में अधिक कुशल होने के बावजूद, भले ही यह वन-लाइनर न हो।
एड्रियन

1
@ एड्रियन मैं सवाल करता हूं कि मुझे लगता है कि addAllO ( n ) होगा।
स्टीव पॉवेल

1
मेरा मानना ​​है कि एड्रियन की बात इस बारे में थी कि कैसे एसएलएसी का समाधान एक सूची उदाहरण बनाता है जिसे अंततः बाहर निकाल दिया जाता है। उस अंतर का वास्तविक प्रभाव शायद बेहद कम है, लेकिन आप उस संदर्भ पर निर्भर कर सकते हैं जिसमें आप यह कर रहे हैं - तंग छोरों या बहुत बड़े सेट इन दो विकल्पों के बीच बहुत अलग तरीके से व्यवहार कर सकते हैं।
JavadocMD

13
प्रति संग्रह .addAll () javadoc (Java 6): "इस सुविधा पद्धति का व्यवहार c.addAll (Arrays.asList (तत्व)) के समान है, लेकिन अधिकांश कार्यान्वयनों के तहत यह विधि बहुत तेज़ी से चलने की संभावना है। "
बर्ट एफ

124

अमरूद के साथ आप कर सकते हैं:

T[] array = ...
Set<T> set = Sets.newHashSet(array);

27
यह भी ImmutableSet.copyOf (सरणी)। (मुझे यह भी इंगित करना पसंद है, मुझे लगता है।)
केविन बॉरिलिन

आपके द्वारा उपयोग किए जा सकने वाले तत्वों की एक निश्चित सूची के लिए: ImmutableSet.of (e1, e2, ..., en)। ध्यान दें कि आप इस सेट को इसके निर्माण के बाद नहीं बदल पाएंगे।
पिसरुक

1
सावधान रहें, अमरूद जेवाडॉक कहता है: "यह विधि वास्तव में बहुत उपयोगी नहीं है और भविष्य में इसकी संभावना कम हो जाएगी।" वे मानक की ओर इशारा करते हैं new HashSet<T>(Arrays.asList(someArray))Google.github.io/guava/releases/19.0/api/docs/com/google/common/…
अलेक्जेंडर क्लिमेत्स्क

67

जावा 8:

String[] strArray = {"eins", "zwei", "drei", "vier"};

Set<String> strSet = Arrays.stream(strArray).collect(Collectors.toSet());
System.out.println(strSet);
// [eins, vier, zwei, drei]

2
क्या यह समानांतर में ऐसा करने लायक है?
रफी खाचदौरेन

@RaffiKhatchadourian यह जरूरी नहीं कि समानांतर में किया जा रहा है। Arrays.stream स्ट्रीम पर कोई वादा नहीं करता है। आपको इसके लिए परिणामी धारा पर समानांतर () कॉल करना होगा।
फेलिक्स एस

आप समानांतर स्ट्र्रीम () भी कह सकते हैं। @ RaffiKhatchadourian के सवाल का जवाब देने के लिए, शायद नहीं। यदि आप किसी भी प्रदर्शन समस्याओं को देख रहे हैं, तो मापने का प्रयास करें।
रैंडी द देव

6
आम तौर पर, समानांतर से बचें। डिफ़ॉल्ट रूप से यह आपके एप्लिकेशन के चारों ओर एक एकल थ्रेडपूल का उपयोग करता है, और थ्रेड शुरू करने और जुड़ने के लिए ओवरहेड सैकड़ों वस्तुओं के माध्यम से क्रमिक रूप से स्ट्रीमिंग से भी बदतर है। केवल बहुत कम स्थितियों में ही समानांतर वास्तव में लाभ पहुंचाता है।
trruse


30

जावा 8

हमारे पास उपयोग करने का भी विकल्प है Stream। हम विभिन्न तरीकों से स्ट्रीम प्राप्त कर सकते हैं:

Set<String> set = Stream.of("A", "B", "C", "D").collect(Collectors.toCollection(HashSet::new));
System.out.println(set);

String[] stringArray = {"A", "B", "C", "D"};
Set<String> strSet1 = Arrays.stream(stringArray).collect(Collectors.toSet());
System.out.println(strSet1);

// if you need HashSet then use below option.
Set<String> strSet2 = Arrays.stream(stringArray).collect(Collectors.toCollection(HashSet::new));
System.out.println(strSet2);

Collectors.toSet()शो का स्रोत कोड दिखाता है कि तत्वों को एक-एक करके जोड़ा जाता है, HashSetलेकिन विनिर्देश यह गारंटी नहीं देता है कि यह एक होगा HashSet

"सेट के प्रकार, परिवर्तनशीलता, क्रमबद्धता या थ्रेड-सुरक्षा पर कोई गारंटी नहीं है।"

इसलिए बाद के विकल्प का उपयोग करना बेहतर है। आउटपुट है: [A, B, C, D] [A, B, C, D] [A, B, C, D]

अचल सेट (जावा 9)

जावा 9 ने Set.ofस्थैतिक कारखाना विधि की शुरुआत की जो प्रदत्त तत्वों या सरणी के लिए अपरिवर्तनीय सेट लौटाता है।

@SafeVarargs
static <E> Set<E> of​(E... elements)

विवरण के लिए अपरिवर्तनीय सेट स्थैतिक फैक्टरी विधियों की जाँच करें

अचल सेट (जावा 10)

हम दो तरीकों से एक अपरिवर्तनीय सेट भी प्राप्त कर सकते हैं:

  1. Set.copyOf(Arrays.asList(array))
  2. Arrays.stream(array).collect(Collectors.toUnmodifiableList());

Collectors.toUnmodifiableList()आंतरिक रूप से Set.ofजावा 9 में शुरू की गई विधि का उपयोग करता है । अधिक के लिए मेरा यह उत्तर भी देखें ।


1
+1 के लिए Stream.of()- मुझे नहीं पता था कि एक। के बारे में एक छोटी सी वक्रोक्ति Collectors.toSet(): आप कहते हैं कि कल्पना एक-एक करके तत्वों को जोड़ने की गारंटी नहीं देती है, लेकिन इसका मतलब यह है कि: "संचित ... एक नए में Set"। और यह अधिक पठनीय है - इसलिए मेरे दिमाग के लिए बेहतर है, अगर आपको ठोस प्रकार, परिवर्तनशीलता, क्रमबद्धता और थ्रेड-सुरक्षा की गारंटी की आवश्यकता नहीं है।
एंड्रयू स्पेन्सर

@AndrewSpencer स्पेक गारंटी नहीं देता है कि सेट कार्यान्वयन होगा HashSet। यह केवल गारंटी देता है कि यह एक होगा Setऔर यही मेरा मतलब है। आशा है कि मैंने इसे स्पष्ट किया।
akhil_mittal

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

19

आपके द्वारा किए जाने के बाद आप Arrays.asList(array)निष्पादित कर सकते हैंSet set = new HashSet(list);

यहाँ एक नमूना विधि है, आप लिख सकते हैं:

public <T> Set<T> GetSetFromArray(T[] array) {
    return new HashSet<T>(Arrays.asList(array));
}

मैं एक ऐसी विधि के लिए उम्मीद कर रहा था जो किसी सरणी से सीधे सेट लौटाता है, क्या कोई मौजूद है?

1
आप अपने खुद के लिख सकते हैं, अगर आप इतने उत्सुक हैं :)
पेटार मिनचेव

12

में ग्रहण संग्रह , निम्नलिखित काम करेंगे:

Set<Integer> set1 = Sets.mutable.of(1, 2, 3, 4, 5);
Set<Integer> set2 = Sets.mutable.of(new Integer[]{1, 2, 3, 4, 5});
MutableSet<Integer> mutableSet = Sets.mutable.of(1, 2, 3, 4, 5);
ImmutableSet<Integer> immutableSet = Sets.immutable.of(1, 2, 3, 4, 5);

Set<Integer> unmodifiableSet = Sets.mutable.of(1, 2, 3, 4, 5).asUnmodifiable();
Set<Integer> synchronizedSet = Sets.mutable.of(1, 2, 3, 4, 5).asSynchronized();
ImmutableSet<Integer> immutableSet = Sets.mutable.of(1, 2, 3, 4, 5).toImmutable();

नोट: मैं ग्रहण संग्रहों के लिए एक कमिटेटर हूं


7

जल्दी से: आप कर सकते हैं:

// Fixed-size list
List list = Arrays.asList(array);

// Growable list
list = new LinkedList(Arrays.asList(array));

// Duplicate elements are discarded
Set set = new HashSet(Arrays.asList(array));

और रिवर्स करने के लिए

// Create an array containing the elements in a list
Object[] objectArray = list.toArray();
MyClass[] array = (MyClass[])list.toArray(new MyClass[list.size()]);

// Create an array containing the elements in a set
objectArray = set.toArray();
array = (MyClass[])set.toArray(new MyClass[set.size()]);

6

मैंने ऊपर दी गई सलाह से नीचे लिखा है - इसे चोरी करें ... यह अच्छा है!

/**
 * Handy conversion to set
 */
public class SetUtil {
    /**
     * Convert some items to a set
     * @param items items
     * @param <T> works on any type
     * @return a hash set of the input items
     */
    public static <T> Set<T> asSet(T ... items) {
        return Stream.of(items).collect(Collectors.toSet());
    }
}

Arrays.stream उपरोक्त के लिए Stream.of से बेहतर हो सकती है।
एशले फ्रिज़

5

वहाँ महान जवाब का एक बहुत पहले से ही किया गया है, लेकिन उनमें से ज्यादातर पुरातन की सरणी के साथ काम नहीं करेगा (जैसे int[], long[], char[], byte[], आदि)

जावा 8 और इसके बाद के संस्करण में, आप सरणी को बॉक्स में रख सकते हैं:

Integer[] boxedArr = Arrays.stream(arr).boxed().toArray(Integer[]::new);

फिर धारा का उपयोग करके सेट में परिवर्तित करें:

Stream.of(boxedArr).collect(Collectors.toSet());

0

कुछ मानक पुस्तकालयों का उपयोग करने में बहुत मदद मिलती है। अपाचे कॉमन्स कलेक्शंस को देखने की कोशिश करें । इस मामले में आपकी समस्याएं बस कुछ इस तरह से बदल जाती हैं

String[] keys = {"blah", "blahblah"}
Set<String> myEmptySet = new HashSet<String>();
CollectionUtils.addAll(pythonKeywordSet, keys);

और यहाँ कलेक्शंस यूटिल्स जेवाडॉक है


4
उपयोगकर्ता अपाचे कॉमन का उपयोग नहीं कर सकता है
एड्रियन

यदि उपयोगकर्ता एपाचे कॉमन्स का उपयोग नहीं करता है, तो यह उसकी पहली गलती है।
Jeryl कुक

3
आप इसके बजाय इसका उपयोग क्यों करेंगे java.util.Collections.addAll(myEmptySet, keys);??
djikybb


0

में जावा 10 :

String[] strs = {"A", "B"};
Set<String> set = Set.copyOf(Arrays.asList(strs));

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

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


0
private Map<Integer, Set<Integer>> nobreaks = new HashMap();
nobreaks.put(1, new HashSet(Arrays.asList(new int[]{2, 4, 5})));
System.out.println("expected size is 3: " +nobreaks.get(1).size());

आउटपुट है

expected size is 3: 1

इसे बदलो

nobreaks.put(1, new HashSet(Arrays.asList( 2, 4, 5 )));

आउटपुट है

expected size is 3: 3

-1

Android के लिए किसी को भी हल करने के लिए:

कोटलिन कलेक्शन सॉल्यूशन

तारांकन *है spreadऑपरेटर। यह एक संग्रह में सभी तत्वों को व्यक्तिगत रूप से लागू करता है, प्रत्येक एक varargविधि पैरामीटर के क्रम में पारित हुआ । यह इसके बराबर है:

val myArray = arrayOf("data", "foo")
val mySet = setOf(*myArray)

// Equivalent to
val mySet = setOf("data", "foo")

// Multiple spreads ["data", "foo", "bar", "data", "foo"]
val mySet = setOf(*myArray, "bar", *myArray)

किसी भी पैरामीटर को setOf()खाली सेट में पास करने का परिणाम नहीं होता है ।

इसके अलावा setOf, आप विशिष्ट हैश प्रकार के लिए इनमें से किसी का भी उपयोग कर सकते हैं:

hashSetOf()
linkedSetOf()
mutableSetOf()
sortableSetOf()

यह संग्रह के प्रकार को स्पष्ट रूप से परिभाषित करने का तरीका है।

setOf<String>()
hashSetOf<MyClass>()

-2

new HashSet<Object>(Arrays.asList(Object[] a));

लेकिन मुझे लगता है कि यह अधिक कुशल होगा:

final Set s = new HashSet<Object>();    
for (Object o : a) { s.add(o); }         

यह वास्तव में अधिक कुशल नहीं होगा (कम से कम इसके बारे में सोचने लायक नहीं है)।
कॉलिनड

3
निर्माता संस्करण के साथ HashSet, उदाहरण के लिए, सरणी के आकार के आधार पर सेट की प्रारंभिक क्षमता है ।
कोलिनड

3
यह उत्तर इतना गूंगा नहीं है जितना लगता है: 'Collections.addAll (mySet, myArray);' java.util.Collections से एक ही पुनरावृत्ति लेकिन प्लस एक बूलियन ऑपरेशन का उपयोग करें। प्लस बर्ट एफ c.addAll से Collections.addAll बाहर "संभावना काफी तेजी अधिकांश प्रयोगों के तहत चलाने के लिए" बताया के रूप में (Arrays.asList (तत्व))
Zorb

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