How to convert an Array to a Set in Java

JavaCollectionsArraysSet

Java Problem Overview


I would like to convert an array to a Set in Java. There are some obvious ways of doing this (i.e. with a loop) but I would like something a bit neater, something like:

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

Any ideas?

Java Solutions


Solution 1 - Java

Like this:

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

In Java 9+, if unmodifiable set is ok:

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

In Java 10+, the generic type parameter can be inferred from the arrays component type:

var mySet = Set.of(someArray);

Be careful

> Set.of throws IllegalArgumentException - if there are any duplicate > elements in someArray. See more details: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html#of(E...)

Solution 2 - Java

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

That's Collections.addAll(java.util.Collection, T...) from JDK 6.

Additionally: what if our array is full of primitives?

For JDK < 8, I would just write the obvious for loop to do the wrap and add-to-set in one pass.

For JDK >= 8, an attractive option is something like:

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

Solution 3 - Java

With Guava you can do:

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

Solution 4 - Java

Java 8:

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

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

Solution 5 - Java

Varargs will work too!

Stream.of(T... values).collect(Collectors.toSet());

Solution 6 - Java

Java 8

We have the option of using Stream as well. We can get stream in various ways:

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);

The source code of Collectors.toSet() shows that elements are added one by one to a HashSet but specification does not guarantee it will be a HashSet.

> "There are no guarantees on the type, mutability, serializability, or > thread-safety of the Set returned."

So it is better to use the later option. The output is: [A, B, C, D] [A, B, C, D] [A, B, C, D]

Immutable Set (Java 9)

Java 9 introduced Set.of static factory method which returns immutable set for the provided elements or the array.

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

Check Immutable Set Static Factory Methods for details. Immutable Set (Java 10)

We can also get an immutable set in two ways:

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

The method Collectors.toUnmodifiableList() internally makes use of Set.of introduced in Java 9. Also check this answer of mine for more.

Solution 7 - Java

After you do Arrays.asList(array) you can execute Set set = new HashSet(list);

Here is a sample method, you can write:

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

Solution 8 - Java

There has been a lot of great answers already, but most of them won't work with array of primitives (like int[], long[], char[], byte[], etc.)

In Java 8 and above, you can box the array with:

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

Then convert to set using stream:

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

Solution 9 - Java

In Eclipse Collections, the following will work:

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();

Note: I am a committer for Eclipse Collections

Solution 10 - Java

Quickly : you can do :

// 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));

and to reverse

// 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()]);

Solution 11 - Java

I've written the below from the advice above - steal it... it's nice!

/**
 * 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());
    }
}

Solution 12 - Java

Sometime using some standard libraries helps a lot. Try to look at the Apache Commons Collections. In this case your problems is simply transformed to something like this

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

And here is the CollectionsUtils javadoc

Solution 13 - Java

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());

the output is

expected size is 3: 1

change it to

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

the output is

expected size is 3: 3

Solution 14 - Java

In Java 10:

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

Set.copyOf returns an unmodifiable Set containing the elements of the given Collection.

 The given Collection must not be null, and it must not contain any null elements.

Solution 15 - Java

Use CollectionUtils or ArrayUtils from stanford-postagger-3.0.jar

import static edu.stanford.nlp.util.ArrayUtils.asSet;
or 
import static edu.stanford.nlp.util.CollectionUtils.asSet;

  ...
String [] array = {"1", "q"};
Set<String> trackIds = asSet(array);
    

Solution 16 - Java

For anyone solving for Android:

Kotlin Collections Solution

The asterisk * is the spread operator. It applies all elements in a collection individually, each passed in order to a vararg method parameter. It is equivalent to:

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)

Passing no parameters setOf() results in an empty set.

In addition to setOf, you can also use any of these for a specific hash type:

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

This is how to define the collection item type explicitly.

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

Solution 17 - Java

If you need to build an immutable set with only one element inside it, you can use Collections.singleton(...). Here is an example:

Set<String> mySet = Collections.singleton("Have a good day :-)");

This doesn't answer the original question but might be useful to someone (it would have been at least to me). If you think this answer does not fit just tell me and I will delete it.

Solution 18 - Java

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

But I think this would be more efficient:

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

Solution 19 - Java

Set<T> b = new HashSet<>(Arrays.asList(requiredArray));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser130076View Question on Stackoverflow
Solution 1 - JavaSLaksView Answer on Stackoverflow
Solution 2 - JavaJavadocMDView Answer on Stackoverflow
Solution 3 - JavaColinDView Answer on Stackoverflow
Solution 4 - JavamaxView Answer on Stackoverflow
Solution 5 - JavaAlexView Answer on Stackoverflow
Solution 6 - Javaakhil_mittalView Answer on Stackoverflow
Solution 7 - JavaPetar MinchevView Answer on Stackoverflow
Solution 8 - JavaKennardView Answer on Stackoverflow
Solution 9 - JavaDonald RaabView Answer on Stackoverflow
Solution 10 - JavaPierre-Olivier PignonView Answer on Stackoverflow
Solution 11 - JavaAshley FriezeView Answer on Stackoverflow
Solution 12 - JavamnagniView Answer on Stackoverflow
Solution 13 - JavaBruce ZuView Answer on Stackoverflow
Solution 14 - JavaOleksandr PyrohovView Answer on Stackoverflow
Solution 15 - JavaOlexandra DmytrenkoView Answer on Stackoverflow
Solution 16 - JavaGiboltView Answer on Stackoverflow
Solution 17 - JavaStypoxView Answer on Stackoverflow
Solution 18 - JavaBen SView Answer on Stackoverflow
Solution 19 - JavaSatyendra JaiswalView Answer on Stackoverflow