Velvet Star Monitor

Standout celebrity highlights with iconic style.

general

Java 8 Streams : Converting a list of objects to a set of objects

Writer Sebastian Wright

I am trying Converting a list of objects to a set of objects to make sure if there is no duplicates exists in the collection. I am trying it using Streams.

I have a class Product as below :

class Product{
int id;
String name;
float price;
public Product(int id, String name, float price) { this.id = id; this.name = name; this.price = price;
} public String getName() { return this.name; } public int getId() { return this.id; } public float getPrice() { return this.price; } public void setName(String name) { this.name = name; } public void setId(int id) { this.id = id; } public void getPrice(float price) { this.price = price; }
} 

I am trying something Like:

 List<Product> productsList = new ArrayList<Product>(); //Adding Products productsList.add(new Product(1,"HP Laptop",25000f)); productsList.add(new Product(2,"Dell Laptop",30000f)); productsList.add(new Product(3,"Lenevo Laptop",28000f)); productsList.add(new Product(4,"Sony Laptop",28000f)); productsList.add(new Product(5,"Apple Laptop",90000f)); productsList.add(new Product(5,"Apple Laptop",90000f)); 

I want the resultant to be stored as Set:

 Set<Product> productPriceList=productsList.stream() .map(p->new Product(p.getId,p.getName,p.getPrice)) .collect(Collectors.toSet()); 

But it's not working for me. Any suggestions would be highly appriciated !

3

3 Answers

Your code will almost compile, you just missed the parentheses off p.getId etc.:

Set<Product> productPriceList = productsList.stream() .map(p -> new Product(p.getId(), p.getName(), p.getPrice())) .collect(Collectors.toSet());

However, your Product must override equals and hashCode if you want the set to work properly. You can see this question for why.

2

As @Khelwood pointed out you need to mention the rule of equality. How does JVM know when to consider two Products as equal?. The product is not a primitive data type and thus JVM only treats it as an object. Read about overriding equals and hashcode and its usage and implications. Just as an advice, It will be of great use to spend some time reading about it rather than jumping into solutions.

Edit: I see many similar answers already posted. Did not see it while writing my suggestions but looks like you got the idea why it is failing. good luck !!

3

It's not clear why you are creating new Product instances to store in the Set. You can simply create a Stream and immediately collect to a Set:

 Set<Product> productPriceList = productsList.stream().collect(Collectors.toSet()); 

However, you must override equals() and hashCode() in order for the Set created by the Stream pipeline to correctly eliminate duplicates (since the current implementation of toSet() returns a HashSet, which requires these methods to be overridden).

Of course, the same result can be obtained without Streams:

Set<Product> productPriceList = new HashSet<>(productPriceList);
2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy