user130076
user130076

Reputation:

How to convert an Array to a Set in Java

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?

Upvotes: 852

Views: 835568

Answers (19)

SLaks
SLaks

Reputation: 887433

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

If you want an unmodifiable set and you might have duplicate elements in the array, do the following:

var mySet = Set.copyOf(Arrays.asList(array));

Upvotes: 1424

Stypox
Stypox

Reputation: 1200

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.

Upvotes: 0

Gibolt
Gibolt

Reputation: 47127

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

Upvotes: 0

Bruce Zu
Bruce Zu

Reputation: 507

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

Upvotes: 0

Kennard
Kennard

Reputation: 875

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

Upvotes: 19

akhil_mittal
akhil_mittal

Reputation: 24157

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.

Upvotes: 37

Oleksandr Pyrohov
Oleksandr Pyrohov

Reputation: 16216

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.

Upvotes: 0

Olexandra Dmytrenko
Olexandra Dmytrenko

Reputation: 99

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

Upvotes: 0

Alex
Alex

Reputation: 623

Varargs will work too!

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

Upvotes: 51

Donald Raab
Donald Raab

Reputation: 6686

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

Upvotes: 12

Ashley Frieze
Ashley Frieze

Reputation: 5443

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

Upvotes: 7

JavadocMD
JavadocMD

Reputation: 4447

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

Upvotes: 248

Satyendra Jaiswal
Satyendra Jaiswal

Reputation: 17

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

Upvotes: -4

max
max

Reputation: 791

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]

Upvotes: 72

Ben S
Ben S

Reputation: 69342

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

Upvotes: -1

mnagni
mnagni

Reputation: 9

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

Upvotes: 0

Pierre-Olivier Pignon
Pierre-Olivier Pignon

Reputation: 747

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

Upvotes: 7

Petar Minchev
Petar Minchev

Reputation: 47373

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

Upvotes: 20

ColinD
ColinD

Reputation: 110046

With Guava you can do:

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

Upvotes: 127

Related Questions