6

我有一个简单的问题要问你,我有类 Product 有这样的字段:

private Integer id;
private String category;
private String symbol;
private String desc;
private Double price;
private Integer quantity;

我想根据 ID 从 LinkedHasSet 中删除重复项,例如将具有相同 ID 但数量不同的产品添加到集合中,我想删除(更新)具有相同 ID 的产品,它将通过我的唯一 id 对象,如何要做到这一点?

eg Product: id=1, category=CCTV, symbol=TVC-DS, desc=Simple Camera, price=100.00, quantity=1 Product: id=1, category=CCTV, symbol=TVC-DS, desc=Simple Camera,价格=100.00,数量=3

不会添加到设置中

我的代码:

    public void setList(Set<Product> list) {
    if(list.isEmpty()) 
        this.list = list;
    else {
        this.list.addAll(list);
        Iterator<Product> it = this.list.iterator();
        for(Product p : list) {
            while(it.hasNext()) {
                if(it.next().getId() != p.getId())
                    it.remove();
                    this.list.add(p);   
            }
        }
    }
}
4

5 回答 5

17

所有Set实现都删除重复项,LinkedHashSet也不例外。

equals()重复的定义是两个对象,根据它们的方法,它们彼此相等。如果您没有覆盖equals您的Product类,那么只有相同的引用将被视为相等 - 而不是具有相同值的不同实例。

因此,您需要为您的课程添加更具体的equals(and hashcode) 实现。有关一些示例和指导,请参阅在 Java 中覆盖等号和哈希码。(请注意,您也必须重写hashcode,否则您的类在哈希集中的行为将不正确。)

于 2013-02-07T09:53:27.913 回答
2

我不会直接回答你,而是给你一些建议。

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

    class OrderLine {
      private Product product;
      private Integer quantity; 
    }
    

    有了这样的设计,很容易回答第 2 点的问题。Product.equals()应该只比较 ID,OrderLine.equals()同时比较产品 (ID)数量。

于 2013-02-07T10:06:47.000 回答
1

我建议你实现自己的哈希函数,用相同的代码对具有相同 ID-s 的元素进行哈希处理。这将解决您的问题,而无需您明确编码。

于 2013-02-07T09:54:01.103 回答
0

该代码似乎两次添加到列表中。在addAll()调用期间一次,然后在迭代期间再次。在这种情况下,我相信第二次迭代就足够了。比较也应该修改为使用equals而不是==

public void setList(Set<Product> list) {
    if(list.isEmpty()) 
        this.list = list;
    else {
        //this.list.addAll(list); Do not add all
        Iterator<Product> it = this.list.iterator();
        for(Product p : list) {
            while(it.hasNext()) {
                if(it.next().getId().equals(p.getId()))
                {
                    this.list.add(p);
                }   
            }
        }
    }
}
于 2013-02-07T09:54:48.350 回答
0

正如其他人已经说过的那样,您将需要从接口实现 (override equals())hashCode()和 (最好) 。如果未正确实施这些方法,可能会导致意外的运行时行为。难以调试问题。因此,我建议您使用,和来实现这些方法。如何使用的示例可以在此链接中看到http://www.javaworld.com/community/node/1859compareTo()ComparableApache Commons EqualsBuilderHashcodeBuilderComparableBuilderApache Commons builder

于 2013-02-07T10:06:35.720 回答