LinkedHashSet删除重复对象
我有一个简单的问题,我有类产品,有这样的字段:
private Integer id; private String category; private String symbol; private String desc; private Double price; private Integer quantity;
我想根据ID删除LinkedHasSet中的重复项,例如具有相同ID但不同数量的产品将被添加到set中,我想删除(更新)具有相同ID的产品,并且它将由我唯一的id对象,如何要做到这一点?
例如产品:id = 1,类别= CCTV,符号= TVC-DS,desc =简单相机,价格= 100.00, 数量= 1产品:id = 1,类别= CCTV,符号= TVC-DS,desc =简单相机,价格= 100.00, 数量= 3
不会被添加到设置中
我的代码:
public void setList(Set list) { if(list.isEmpty()) this.list = list; else { this.list.addAll(list); Iterator it = this.list.iterator(); for(Product p : list) { while(it.hasNext()) { if(it.next().getId() != p.getId()) it.remove(); this.list.add(p); } } } }
所有Set
实现都删除重复项, LinkedHashSet
也不例外。
根据equals()
方法,复制的定义是两个彼此相等的对象。 如果您没有在Product
类上重写equals
,那么只有相同的引用才会被视为相同 – 而不是具有相同值的不同实例。
因此,您需要为您的类添加更具体的equals
(和hashcode
)实现。 有关示例和指导,请参阅在Java中覆盖equals和hashcode 。 (请注意,您还必须覆盖hashcode
,否则您的类在哈希集中将无法正常运行。)
我不会直截了当地给你答案,而是给你一些建议。
- 如果要将
Product
放入Set
,则需要实现其equals()
和hashCode()
方法。 - 实现
equals()
您必须决定Product
“相等性”意味着什么 (Set
在“相等”方面只能包含一个实例)。 例如,如果两个Product
实例“相等”,如果它们具有相同的ID或者我们是否还要考虑数量就足够了? 在你的案例中回答这个问题并不容易,但请继续阅读。 - 通常在这种情况下,只考虑ID。 在这种情况下,您不应该在内存中有两个具有不同
quantities
Product
实例,因为其中一个将表示不正确的状态(即特定产品的数量可以是1或3,而不是一次两个)。 -
我认为设计并不完全正确。 您的
Product
类别代表一般产品描述(包括价格),因此quantity
并不适合那里。 如果有人可以订购几份Product
我认为您应该创建另一个类,例如Order
或OrderLine
,它指定订购的产品和相应的数量,例如:class OrderLine { private Product product; private Integer quantity; }
使用这样的设计,可以很容易地从第2点回答问题
Product.equals()
应该只比较ID,而OrderLine.equals()
应该比较产品(ID) 和数量。
我建议你实现自己的哈希函数,使其具有相同ID-s的具有相同代码的元素。 这将解决您的问题,而无需您明确地对其进行编码。
代码似乎两次添加到列表中。 一旦在addAll()
调用期间再次在迭代期间再次调用。 在这种情况下,我相信第二次迭代就足够了。 还应修改比较以使用equals
而不是==
public void setList(Set list) { if(list.isEmpty()) this.list = list; else { //this.list.addAll(list); Do not add all Iterator it = this.list.iterator(); for(Product p : list) { while(it.hasNext()) { if(it.next().getId().equals(p.getId())) { this.list.add(p); } } } } }
正如其他人已经说过的那样,你需要在Comparable
接口中实现(覆盖) equals()
, hashCode()
和(prefarably) compareTo()
。 如果未正确实现,这些方法可能会导致意外的运行时行为。 很难调试问题。 因此,我建议您使用Apache Commons
EqualsBuilder
, HashcodeBuilder
和ComparableBuilder
来实现这些方法。 有关如何使用Apache Commons builder
的示例, Apache Commons builder
链接http://www.javaworld.com/community/node/1859