By user130076


2010-06-17 18:23:56 8 Comments

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?

17 comments

@Julia 2018-12-17 01:08:07

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

@SLaks 2010-06-17 18:27:37

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

@despot 2011-07-06 10:06:52

I would leave out the last <T>, otherwise nice oneliner!

@SLaks 2012-06-08 18:34:09

@dataoz: Wrong; Arrays.asList is O(1).

@Jagat 2012-06-25 13:12:09

@SLaks Exactly. asList just creates a view on top of the array.

@dataoz 2012-07-12 19:33:37

@SLaks I exaggerated a bit. But you still create 1 more object than if you iterated over the array yourself or used the helper method provided by Collections, as indicated by JavadocMD below. That is unless I am missing something obvious.

@T. Markle 2012-09-22 04:53:44

Note that if you use this method on an array of primitives such as int[] it will return a List<int[]> so you should use wrapper classes to get the intended behavior.

@PNS 2013-03-04 18:41:49

Actually, if you put the code in a method with a generic return type <T>, attempting to pass a primitive array as T[] won't compile, so no problem. Otherwise, one would need to check someArray.getClass().getComponentType().isPrimitive().

@Ajay Gautam 2013-10-02 19:01:16

Sets.newHashSet is a cleaner solution

@SLaks 2013-10-02 19:15:22

@AjayGautam: That's only in Guava.

@David Carboni 2015-04-21 14:29:56

I'll take readability over efficiency (nearly) every time: blog.codinghorror.com/…

@Nayuki 2016-03-01 02:37:12

@yegor256 The valid explicit syntax is Arrays.<T>asList(). But it is better to rely on type inference whenever possible.

@oleg.cherednik 2017-08-01 15:19:18

Set<String> set = Collections.asSet("one", "two");

@Damith 2018-07-30 04:24:18

There is a major difference between using new HashSet<T>(Arrays.asList(someArray)); and Set.of(someArray); that is, former produces a Non-Immutable collection while later produce an immutable collection.

@Vikash Kumar 2019-01-04 18:46:25

I observed that new HashSet<T>(Arrays.asList(someArray)); would not add each element separately , it just adds the whole array as set's first item .

@Samuel Noyes 2019-10-26 09:19:01

The time complexities of all of these solutions are O(n), correct? I assume there is no faster way to do it.

@i_am_zero 2015-06-24 05:38:43

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.

@Andrew Spencer 2016-02-19 09:00:08

+1 for Stream.of() - I didn't know that one. A small quibble about Collectors.toSet(): you say the spec does not guarantee adding elements one by one, but that's what it means by: "accumulates ... into a new Set". And it's more readable - so preferable to my mind, if you don't need the guarantees of concrete type, mutability, serializability and thread-safety.

@i_am_zero 2016-02-20 10:12:16

@AndrewSpencer Spec does not guarantee that the set implementation will be HashSet. It only guarantees that it will be a Set and that is what I mean. Hope I clarified it.

@Andrew Spencer 2016-02-24 10:36:43

Sorry, and thanks, I misread it as meaning "spec does not guarantee added one by one" rather than "spec does not guarantee a HashSet". Proposed an edit to clarify.

@Oleksandr Pyrohov 2018-04-14 20:59:11

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.

@Olexandra Dmytrenko 2018-05-21 21:26:45

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

@Alex 2015-09-16 07:44:48

Varargs will work too!

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

@senseiwu 2018-02-26 13:55:18

way better that 2-3 liners.

@Donald Raab 2012-12-18 23:04:29

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

@Bruce Zu 2016-08-28 20:34:46

    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

@Ashley Frieze 2016-04-28 22:10:39

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

@Ashley Frieze 2016-12-03 10:17:34

Arrays.stream may be better than Stream.of for the above.

@JavadocMD 2010-06-17 18:37:50

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

@ColinD 2010-06-17 18:40:04

You can do that with java.util.Collections.addAll. Plus, I wouldn't recommend Commons Collections anymore, what with it not being generified and Guava existing .

@Adrian 2012-04-10 22:17:15

+1 for being more efficient than SLaks's answer, even though it's not a one-liner.

@Steve Powell 2013-10-22 15:35:37

@Adrian I question that. I think addAll will be O(n).

@JavadocMD 2013-10-22 19:00:22

I believe Adrian's point was about how SLaks' solution creates a List instance which is ultimately thrown out. The actual impact of that difference is probably extremely minimal, but could depend on the context in which you're doing this -- tight loops or very large sets might behave very differently between these two options.

@Bert F 2014-02-03 22:50:42

Per the Collections.addAll() javadoc (Java 6): "The behavior of this convenience method is identical to that of c.addAll(Arrays.asList(elements)), but this method is likely to run significantly faster under most implementations."

@downeyt 2015-07-18 14:02:28

Interesting fact? Coding in NetBeans, I wrote my own loop to copy the array to the set. NetBeans popped up a light bulb suggesting I use mySet.addAll(Arrays.asList(myArray));

@user2418306 2016-04-11 20:10:18

Won't work for an array of primitives.

@JavadocMD 2016-04-13 23:34:14

@user2418306 Indeed! Of course you can't have a collection of primitives anyway, so you're going to have to wrap them. Edited with recommendations.

@Andreas 2018-04-24 17:45:24

JDK 9+ (not primitives): Set.of(myArray)

@Satyendra Jaiswal 2016-01-12 12:20:04

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

@Ferrybig 2016-01-19 17:16:29

In what aspect does you answer differ from the implementation @SLaks has provided as least 6 years ago? stackoverflow.com/a/3064447

@Thanga 2017-06-28 06:55:03

duplicate answer...

@max 2015-02-02 16:03:20

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]

@Raffi Khatchadourian 2016-01-06 18:10:40

Is it worth doing this in parallel?

@Felix S 2016-01-20 11:41:27

@RaffiKhatchadourian This is not necessarily being done in parallel. Arrays.stream does not make any promises on the stream. You would have to call parallel() on the resulting stream for that.

@Randy the Dev 2016-12-01 00:14:18

You could also call parallelStream(). To answer @RaffiKhatchadourian's question, probably not. Try measuring if you're noticing any performance issues.

@tkruse 2017-03-03 08:02:36

Generally, avoid parallel. By default it uses a single threadpool accross your application, and the overhead to start threads and join is worse than sequentially streaming through hundreds of items. Only in very few situations does parallel actually bring benefit.

@Ben S 2010-06-17 18:28:44

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

@ColinD 2010-06-17 18:46:54

That wouldn't really be more efficient (at least not worth thinking about).

@ColinD 2010-06-17 18:55:07

With the constructor version, the initial capacity of the HashSet is set based on the size of the array, for instance.

@Zorb 2015-10-14 22:05:13

this answer is not so dumb as it seems: 'Collections.addAll(mySet, myArray);' from java.util.Collections use the same iterator but plus one boolean operation . Plus as Bert F pointed out Collections.addAll " likely to run significantly faster under most implementations" than c.addAll(Arrays.asList(elements))

@mnagni 2012-01-04 17:13:21

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

@Adrian 2012-01-04 17:17:37

user might not use apache commons

@Jeryl Cook 2013-10-04 13:46:22

if the user does not use apache commons, then that is his first mistake.

@djeikyb 2014-12-09 21:10:00

why would you use this instead of java.util.Collections.addAll(myEmptySet, keys);??

@Pierre-Olivier Pignon 2011-11-04 09:30:37

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

@Petar Minchev 2010-06-17 18:27:28

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

@user130076 2010-06-17 18:31:03

I was hoping for a method that returns a set directly from an array, does one exist?

@Petar Minchev 2010-06-17 18:34:54

You can write your own, if you are so eager:)

@ColinD 2010-06-17 18:36:03

With Guava you can do:

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

@Kevin Bourrillion 2010-06-17 21:26:08

also ImmutableSet.copyOf(array). (I like to point out also's, I guess.)

@pisaruk 2016-08-17 17:02:31

For a fixed list of elements you could use: ImmutableSet.of(e1, e2, ..., en). Notice you would not be able to change this Set after its creation.

@Alexander Klimetschek 2016-11-11 01:51:32

Be warned, the Guava javadoc says: "This method is not actually very useful and will likely be deprecated in the future." They point towards the standard new HashSet<T>(Arrays.asList(someArray)). See google.github.io/guava/releases/19.0/api/docs/com/google/com‌​mon/…

Related Questions

Sponsored Content

86 Answered Questions

[SOLVED] Is Java "pass-by-reference" or "pass-by-value"?

26 Answered Questions

88 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6102621 View
  • 7610 Score
  • 88 Answer
  • Tags:   javascript arrays

41 Answered Questions

[SOLVED] Loop through an array in JavaScript

41 Answered Questions

[SOLVED] How do I efficiently iterate over each entry in a Java Map?

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

33 Answered Questions

[SOLVED] What's the simplest way to print a Java array?

  • 2009-01-03 20:39:39
  • Alex Spurling
  • 2154530 View
  • 1842 Score
  • 33 Answer
  • Tags:   java arrays printing

57 Answered Questions

[SOLVED] How do I read / convert an InputStream into a String in Java?

34 Answered Questions

[SOLVED] Create ArrayList from array

17 Answered Questions

[SOLVED] Converting 'ArrayList<String> to 'String[]' in Java

Sponsored Content