781

What is the easiest way to convert a List to a Set in Java?

18 Answers 18

1256
Set<Foo> foo = new HashSet<Foo>(myList);
3
  • 4
    While correct this answer lacks sufficient technical context to warrant being the best/accepted answer, because there are pitfalls here depending on which implementations of Set and Map one is using; HashSet is assumed here.
    – Madbreaks
    Commented Jul 3, 2018 at 17:25
  • 4
    @Madbreaks Came here specifically for that problem and would recommend using Ramesh's solution with Abdul's explanation to anyone else that is interested in trying to do this Commented Jul 12, 2020 at 7:17
  • Better than Baeldung Commented Mar 17, 2023 at 15:56
165

I agree with sepp2k, but there are some other details that might matter:

new HashSet<Foo>(myList);

will give you an unsorted set which doesn't have duplicates. In this case, duplication is identified using the .equals() method on your objects. This is done in combination with the .hashCode() method. (For more on equality look here)

An alternative that gives a sorted set is:

new TreeSet<Foo>(myList);

This works if Foo implements Comparable. If it doesn't then you may want to use a comparator:

Set<Foo> lSet = new TreeSet<Foo>(someComparator);
lSet.addAll(myList);

This depends on either compareTo() (from the comparable interface) or compare() (from the comparator) to ensure uniqueness. So, if you just care about uniqueness, use the HashSet. If you're after sorting, then consider the TreeSet. (Remember: Optimize later!) If time efficiency matters use a HashSet if space efficiency matters, look at TreeSet. Note that more efficient implementations of Set and Map are available through Trove (and other locations).

1
  • Thanks for included the custom Comparator use case! Commented Sep 24, 2018 at 21:44
81

Java- addAll

set.addAll(aList);

Java- new Object

new HashSet<>(list)

Java-8

list.stream().collect(Collectors.toSet());

Using Guva

 Sets.newHashSet(list)

Apache Commons

CollectionUtils.addAll(targetSet, sourceList);

Java 10

var set = Set.copyOf(list);
3
  • 3
    Are there any performance differences among them? Commented Jan 20, 2021 at 4:20
  • 1
    I think this answer should be marked as the best answer. Thanks !
    – Quentame
    Commented Aug 5, 2021 at 9:01
  • I tried this one, list.stream().collect(Collectors.toSet()); but IntelliJ suggested "Can be replaced with 'java.util.HashSet' constructor", so replaced with new HashSet<>(list)
    – Romeo
    Commented Apr 24 at 5:08
75

If you use the Guava library:

Set<Foo> set = Sets.newHashSet(list);

or, better:

Set<Foo> set = ImmutableSet.copyOf(list);
4
  • 4
    Why is ImmutableSet.copyOf better?
    – user672009
    Commented Apr 14, 2016 at 9:05
  • 3
    What advantages does Guava's newHashSet() have over the basic java new HashSet()? Commented May 16, 2016 at 15:20
  • @Nelda.techspiress The javadoc discusses when the method should or should not be used. Note the final part: this method is not very useful and will likely be deprecated in the future. Though I'm a bit surprised consistency is not mentioned as a factor, as it is with ImmutableSet.of(), for example. EDIT: it may not be factor because all the overloads are unneeded.
    – shmosel
    Commented May 30, 2016 at 21:56
  • 2
    Hey thanks for the reference @shmosel, but I was looking more for empirical knowledge. For those who have used Guava, why would Guava be chosen over HashSet? Commented Jun 2, 2016 at 22:02
36

Using java 8 you can use stream:

List<Integer> mylist = Arrays.asList(100, 101, 102);
Set<Integer> myset = mylist.stream().collect(Collectors.toSet()));
3
  • 20
    Have you checked the performance penalty on this? this would do an iterable+iterator, a new HashSet(), and then for each list item, an addAll() call on the new set. Overall, cca. 5 objects created for something as simple as a new HashSet(list). Commented Oct 17, 2016 at 9:17
  • 2
    @AgostonHorvath Thank you for your comment. I was originally looking for that information when I came here. Commented Jun 20, 2019 at 11:44
  • I tried this one, list.stream().collect(Collectors.toSet()); but IntelliJ suggested "Can be replaced with 'java.util.HashSet' constructor", so replaced with new HashSet<>(list)
    – Romeo
    Commented Apr 24 at 6:16
18
Set<E> alphaSet  = new HashSet<E>(<your List>);

or complete example

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ListToSet
{
    public static void main(String[] args)
    {
        List<String> alphaList = new ArrayList<String>();
        alphaList.add("A");
        alphaList.add("B");
        alphaList.add("C");
        alphaList.add("A");
        alphaList.add("B");
        System.out.println("List values .....");
        for (String alpha : alphaList)
        {
            System.out.println(alpha);
        }
        Set<String> alphaSet = new HashSet<String>(alphaList);
        System.out.println("\nSet values .....");
        for (String alpha : alphaSet)
        {
            System.out.println(alpha);
        }
    }
}
1
  • 1
    +1 for a complete code example. One additional note here is that hashing isn't guaranteed to be the same from run to run. That means that the list printed after 'Set values .....' might be 'ABC' one run and 'CBA' another run. As I mentioned in my answer, you could use a tree set to get a stable ordering. Another option would be to use a LinkedHashSet which remembers the order that items were added to it.
    – Spina
    Commented Sep 23, 2013 at 12:45
11

Remember that, converting from List to Set will remove duplicates from collection because List supports duplicates but Set does not support duplicates in Java.

Direct Conversion : The most common and simple way to convert a List to a Set

// Creating a list of strings
List<String> list = Arrays.asList("One", "Two", "Three", "Four");

// Converting a list to set
Set<String> set = new HashSet<>(list);

Apache Commons Collections : You may also use the Commons Collections API to convert a List to a Set :-

// Creating a list of strings
List<String> list = Arrays.asList("One", "Two", "Three", "Four");

// Creating a set with the same number of members in the list 
Set<String> set = new HashSet<>(4);

// Adds all of the elements in the list to the target set
CollectionUtils.addAll(set, list);

Using Stream : Another way is to convert given list to stream, then stream to set :-

// Creating a list of strings 
List<String> list = Arrays.asList("One", "Two", "Three", "Four"); 

// Converting to set using stream 
Set<String> set = list.stream().collect(Collectors.toSet()); 
1
  • I tried this one, list.stream().collect(Collectors.toSet()); but IntelliJ suggested "Can be replaced with 'java.util.HashSet' constructor", so replaced with new HashSet<>(list)
    – Romeo
    Commented Apr 24 at 6:15
8

With Java 10, you could now use Set#copyOf to easily convert a List<E> to an unmodifiable Set<E>:

Example:

var set = Set.copyOf(list);

Keep in mind that this is an unordered operation, and null elements are not permitted, as it will throw a NullPointerException.

If you wish for it to be modifiable, then simply pass it into the constructor a Set implementation.

7

I would perform a Null check before converting to set.

if(myList != null){
Set<Foo> foo = new HashSet<Foo>(myList);
}
1
  • 3
    Or Set<Foo> foo = myList == null ? Collections.emptySet() : new HashSet<Foo>(myList); Commented Dec 30, 2014 at 14:29
6

For Java 8 it's very easy:

List < UserEntity > vList= new ArrayList<>(); 
vList= service(...);
Set<UserEntity> vSet= vList.stream().collect(Collectors.toSet());
1
  • "Real" Java 8 would be to use new ArrayList<>() ;-)
    – J.R.
    Commented Jul 5, 2018 at 6:53
5

You can convert List<> to Set<>

Set<T> set=new HashSet<T>();

//Added dependency -> If list is null then it will throw NullPointerExcetion.

Set<T> set;
if(list != null){
    set = new HashSet<T>(list);
}
1
  • I think you meant casting it from List to Set.
    – Simon
    Commented Dec 27, 2014 at 15:49
5

Let's not forget our relatively new friend, stream API. If you need to preprocess list before converting it to a set, it's better to have something like:

list.stream().<here goes some preprocessing>.collect(Collectors.toSet());
1
  • I tried this one, list.stream().collect(Collectors.toSet()); but IntelliJ suggested "Can be replaced with 'java.util.HashSet' constructor", so replaced with new HashSet<>(list)
    – Romeo
    Commented Apr 24 at 6:16
5

The best way to use constructor

Set s= new HashSet(list);

In java 8 you can also use stream api::

Set s= list.stream().collect(Collectors.toSet());
1
  • I tried this one, list.stream().collect(Collectors.toSet()); but IntelliJ suggested "Can be replaced with 'java.util.HashSet' constructor", so replaced with new HashSet<>(list)
    – Romeo
    Commented Apr 24 at 6:15
3

There are various ways to get a Set as:

    List<Integer> sourceList = new ArrayList();
    sourceList.add(1);
    sourceList.add(2);
    sourceList.add(3);
    sourceList.add(4);

    // Using Core Java
    Set<Integer> set1 = new HashSet<>(sourceList);  //needs null-check if sourceList can be null.

    // Java 8
    Set<Integer> set2 = sourceList.stream().collect(Collectors.toSet());
    Set<Integer> set3 = sourceList.stream().collect(Collectors.toCollection(HashSet::new));

    //Guava
    Set<Integer> set4 = Sets.newHashSet(sourceList);

    // Apache commons
    Set<Integer> set5 = new HashSet<>(4);
    CollectionUtils.addAll(set5, sourceList);

When we use Collectors.toSet() it returns a set and as per the doc:There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned. If we want to get a HashSet then we can use the other alternative to get a set (check set3).

1
  • I tried this one, list.stream().collect(Collectors.toSet()); but IntelliJ suggested "Can be replaced with 'java.util.HashSet' constructor", so replaced with new HashSet<>(list)
    – Romeo
    Commented Apr 24 at 6:16
3

A more Java 8 resilient solution with Optional.ofNullable

Set<Foo> mySet = Optional.ofNullable(myList).map(HashSet::new).orElse(null);
3

If you use Eclipse Collections:

MutableSet<Integer> mSet = Lists.mutable.with(1, 2, 3).toSet();
MutableIntSet mIntSet = IntLists.mutable.with(1, 2, 3).toSet();

The MutableSet interface extends java.util.Set whereas the MutableIntSet interface does not. You can also convert any Iterable to a Set using the Sets factory class.

Set<Integer> set = Sets.mutable.withAll(List.of(1, 2, 3));

There is more explanation of the mutable factories available in Eclipse Collections here.

If you want an ImmutableSet from a List, you can use the Sets factory as follows:

ImmutableSet<Integer> immutableSet = Sets.immutable.withAll(List.of(1, 2, 3))

Note: I am a committer for Eclipse Collections

1

In Java 1.8, the stream API can be used to convert a list to set. For example, the code below shows the conversion of a list to a set:

List<String> empList = Arrays.asList("java", "python", ".net", "javaScript", "php");
Set<String> set = empList.stream().collect(Collectors.toSet());
set.forEach(value -> System.out.printf("%s ", value));

In case the list contains objects and I want to create a set out of it:

List<Employee> empList = Arrays.asList(new Employee(1, 1000, "Chandra Shekhar", 6000),
new Employee(2, 1000, "Rajesh", 8000), new Employee(3, 1004, "Rahul", 9000),
new Employee(4, 1001, "Suresh", 12000), new Employee(5, 1004, "Satosh", 7000));

Set<String> set = empList.stream().map(emp -> emp.getName()).collect(Collectors.toSet());
System.out.println(set);        
1
  • I tried this one, list.stream().collect(Collectors.toSet()); but IntelliJ suggested "Can be replaced with 'java.util.HashSet' constructor", so replaced with new HashSet<>(list)
    – Romeo
    Commented Apr 24 at 6:14
0

EASIEST WAY*

Set foo set = new HashSetfoo(mylist);

System.out.println(set);

Not the answer you're looking for? Browse other questions tagged or ask your own question.