How to convert an Array to a Set in Java
JavaCollectionsArraysSetJava 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)
Immutable Set Static Factory Methods for details. Immutable Set (Java 10)
CheckWe can also get an immutable set in two ways:
Set.copyOf(Arrays.asList(array))
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));