Java 8 Streams:将对象列表转对象集合去重失败求助
解决Java 8 Stream将列表转无重复Set失效的问题
嘿,我来帮你搞定这个问题!你当前的代码没法实现去重,核心原因是你的Product类没有重写equals()和hashCode()方法,而Java里的Set(比如默认的HashSet)是靠这两个方法来判断元素是否重复的。
为什么当前代码失效?
Java默认的equals()方法比较的是对象的内存地址,哪怕两个Product对象的id、name、price完全一样,它们也是不同的实例,Set会把它们当成不同元素存储。你用map重新创建对象的操作更是雪上加霜——哪怕原列表里的两个对象属性相同,你新new出来的也是不同内存地址的对象,Set自然没法识别它们是重复的。
另外还要提一句:你Product类里的getPrice(float price)方法写错了,应该是setPrice(float price),这个小错误可能会导致后续设置价格的操作出问题,记得修正!
解决方案步骤
1. 重写Product类的equals()和hashCode()方法
我们需要基于唯一标识(比如id,因为产品ID应该是唯一的)来重写这两个方法,这样Set就能正确判断两个Product是否是同一个产品。
修改后的Product类代码:
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 setPrice(float price) { this.price = price; } // 重写equals,基于id判断 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Product product = (Product) o; return id == product.id; } // 重写hashCode,基于id生成 @Override public int hashCode() { return Integer.hashCode(id); } }
2. 简化Stream代码
既然已经重写了equals()和hashCode(),你根本不需要用map去创建新的Product对象,直接对原列表的元素进行收集即可:
Set<Product> productPriceList = productsList.stream() .collect(Collectors.toSet());
额外说明
如果你想基于其他规则去重(比如name和price相同就算重复,而不是id),只需要修改equals()和hashCode()的判断逻辑即可——比如同时比较name和price,hashCode也基于这两个属性生成。但通常产品ID是唯一标识,用id来判断重复更合理。
内容的提问来源于stack exchange,提问作者NawazSE
相关产品推荐
相关产品推荐

