java hashset中项的相等性

mar*_*n72 0 java equals hashcode

我需要为一个Item实现equals()方法,该方法可以放在它的Maker的hashset中.Item可以有如下字段

class Item{
    private String isbn;
    private String name;
    private double price;
...
}

class Maker{
    private String name;
    private Set<Item> items;
    public Maker() {
        super();
        items = new HashSet<Item>();
    }
...
}
Run Code Online (Sandbox Code Playgroud)

如果我通过比较三个字段来实现equals并根据这些字段写一个hashCode(),那么我会得到错误的结果

1.add item to hashset
2.modify the price of item
3.try to find if item exists in hashset


@Override
public boolean equals(Object o){
    if(o == this){
        return true;
    }
    if (!(o instanceof Item)){
        return false;
    }
    Item a = (Item)o;
    if(hasSameName(a) && hasSameIsbn(a) && hasSamePrice(a)){
        return true;
    }
    else{
       return false;
    }
}

@Override
public int hashCode(){
    int hash = 41 + this.isbn.hashCode();
    hash = hash*41+ new Double(this.price).hashCode();
    hash = hash*41 + this.name.hashCode();
    return hash;
}

...
Set<Item> items = new HashSet<Item>();
Item item1 = new Item();
item1.setName("crystal bird");
item1.setIsbn("1111");
item1.setPrice(120.5);

items.add(item1);

System.out.println(items.contains(item1));//returns true
item1.setPrice(177.0);
System.out.println(items.contains(item1));//returns false
Run Code Online (Sandbox Code Playgroud)

解决这个问题的解决方案是什么?我应该使hashCode()仅依赖于isbn并假设它在项目的生命周期内不会改变.

任何帮助赞赏

标记.

Boz*_*zho 5

是的,ISBN是典型的自然标识符 - 仅用于equals(..)hashCode()