I need to implement equals() method for an Item that may be put in a hashset of it’s Maker.The Item can have fields as below
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>();
}
...
}
If I implement equals by comparing the three fields and write a hashCode() based on those fields,I will get wrong results when
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
What is the solution to overcome this?Should I make hashCode() depend only on isbn and assume that it will not change during the life of the item.
Any help appreciated
mark.
The
HashSet.add()method (which is basically HashMap.put() method) finds the best place on the self-maintained inner table according to thehashcode().If you change the value of the item That is
KeyinHashMapso it will alter thehashcode()value resulting abnormal result.You should only consider ISBN as a Key for object to keep things as simple as possible.