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 ,否则您的类在哈希集中将无法正常运行。)

我不会直截了当地给你答案,而是给你一些建议。

  1. 如果要将Product放入Set ,则需要实现其equals()hashCode()方法。
  2. 实现equals()您必须决定Product “相等性”意味着什么Set在“相等”方面只能包含一个实例)。 例如,如果两个Product实例“相等”,如果它们具有相同的ID或者我们是否还要考虑数量就足够了? 在你的案例中回答这个问题并不容易,但请继续阅读。
  3. 通常在这种情况下,只考虑ID。 在这种情况下,您不应该在内存中有两个具有不同quantities Product实例,因为其中一个将表示不正确的状态(即特定产品的数量可以是1或3,而不是一次两个)。
  4. 我认为设计并不完全正确。 您的Product类别代表一般产品描述(包括价格),因此quantity并不适合那里。 如果有人可以订购几份Product我认为您应该创建另一个类,例如OrderOrderLine ,它指定订购的产品和相应的数量,例如:

     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 EqualsBuilderHashcodeBuilderComparableBuilder来实现这些方法。 有关如何使用Apache Commons builder的示例, Apache Commons builder链接http://www.javaworld.com/community/node/1859