4

Recently I came across the new syntax of Java 8 that can be used to convert a list to a set:

Set<Integer> myset = mylist.stream().collect(Collectors.toSet()));

I would like to know the advantage of using this approach to convert a list to a set over the traditional way (by passing it as a argument to HashSet.)

4
  • 6
    If that's all your doing, there's no advantage over new HashSet(mylist). If you want to filter or map your stream, then there is an advantage to it. Commented Dec 20, 2017 at 10:40
  • Please do it the old-fashioned way. The makers of the JDK have optimised the constructor of HashSet so that it works efficiently. Doing it with stream() - not so much. Commented Dec 20, 2017 at 10:41
  • @DawoodibnKareem Because HashSets constructor initialises the internal map to a reasonable size before inserting elements? Commented Dec 20, 2017 at 11:30
  • 1
    @Michael, well partly that, and partly because there is real, measurable overhead in creating a stream. Also, we can trust Oracle to ensure that what goes on in the HashSet constructor is "best possible". For me though, one big thing is readability. new HashSet(myList) is easier to understand than myList.stream().collect(Collectors.toSet()), no matter how excited the functional programming evangelists get about the latter. Commented Dec 20, 2017 at 17:40

3 Answers 3

11

The advantage is that it then becomes easier (or more accurately, requires fewer syntactical changes) to perform other functional operations at the same time.

Say later on you just wanted the even numbers in the set, you could then do that trivially with a filter:

Set<Integer> myset = mylist.stream()
        .filter(p -> p%2==0)
        .collect(Collectors.toSet());

If you'd done it the traditional way, then you'd either need to convert it to the above syntax, or write an additional loop to go through and pull out only the values that you wanted.

(This doesn't mean it's always better - there may be cases where you want to discourage someone changing the code at a later date to filter out values, in which case you could argue the traditional way is still preferable.)

Sign up to request clarification or add additional context in comments.

2 Comments

So just to convert list to set, using java 8 does not give a performance improvement over the traditional way and that I should stick to the traditional way for achieving the same.
@TusharBanne Correct (but you shouldn't be writing code based on micro-performance assumptions anyway - stick with what's most readable.) The Java 8 stream API wasn't designed to be a massive performance boost for these types of operations, it provides the ability to write more concise, functional-like code.
1

Please find below code to concert List to Set using stream API of Java 8:

package streamapi;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
class Person{
    int empid;
    String name;
    
    Person(int empid,String name){
        this.empid = empid;
        this.name = name;
    }
    
    public String toString(){
        return "id"+this.empid+"name"+this.name;
    }
    
    public boolean equals(Object obj) {
        Person p = (Person)obj;
        if(p.empid==this.empid && p.name.equals(this.name)) {
            return true;
        }
        return false;
    }
    
    public int hashCode() {
        return this.empid+this.name.hashCode();
    }
}

public class collectionFilter {

    public static void main(String[] args) {
        List<Person> list = new ArrayList();
        list.add(new Person(101,"aaa"));
        list.add(new Person(200,"bbbb"));
        list.add(new Person(150,"ccccc"));
        list.add(new Person(250,"ddddd"));
        list.add(new Person(250,"ddddd"));
        
        converListToSet(list);
    }
    
    public static void converListToSet(List<Person> list) {
        Set<Person> set = list.stream()
                .collect(Collectors.toSet());
        set.forEach(person->System.out.println(person));
    }
}

Output like this:

id200namebbbb
id101nameaaa
id150nameccccc
id250nameddddd

2 Comments

you can see above example that we are adding duplicate Person object in ArrayList and after converting that to list using StreamAPI, we are getting only unique values no duplicate . Copy and run this code once . I hope , you will get clear picture .
Shorthand: set.forEach(System.out::println)
1

You can simply use this precise code:

Set<Integer> myset = new HashSet<>(mylist);

and that's it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.