HashSet、hashcoede()、equals()之間的關係java
當用到散列表時,」hashCode() 和 equals() 」是有關係的!ide
例如:Hashset的插入的判斷順序是:先判斷hashcode,不相同則插入;相同則繼續比較equals是否爲true,若是爲true則表示兩個對象相等,不能插入;若是是false則會散列到其餘位置。this
總結:code
equals=true =》hashcode()相同 、反之不行對象
若是要使用散列表而且重寫了equals方法就必定要重寫hashcode()方法,以保證相同的對象不能同時加入HashSet中。get
爲何重寫equals方法必定要重寫hashcode方法?hash
先看String
類重寫的這兩個方法class
public boolean equals(Object anObject) { //判斷地址是否同樣、同樣則直接返回 if (this == anObject) { return true; } //判斷對象是否屬於String類 if (anObject instanceof String) { //開始比較 String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; } public int hashCode() { //進行hash計算 int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
如今來看本身寫的類(要求 id和name 相同則視爲同一個對象)
一、先看自動生成的者兩個方法
默認生成的比較了book類的全部參數,以及進行了哈希運算。方法
class Book1 { int id; String name; String author; double price; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Book1 book1 = (Book1) o; return id == book1.id && Double.compare(book1.price, price) == 0 && Objects.equals(name, book1.name) && Objects.equals(author, book1.author); } @Override public int hashCode() { return Objects.hash(id, name, author, price); } }
二、要求是di和name相同則視爲同一本書、即同一對象,相同的對象不能加入到散列表中,只須要比較id和name,改寫以下總結
/** * 重寫equals方法比較id和name * @param o * @return */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Book1 book1 = (Book1) o; return id == book1.id && Objects.equals(name, book1.name); } /** * 重寫equals要重寫hashcode set加入時會先判斷hashcode是否相等,再判斷是否equals * 只有hashcode相同 和equals 同時成立 才能保證set的全部元素都不相等 * @return */ @Override public int hashCode() { return Objects.hash(id, name); }
若是隻是改寫了equals方法 hashcode方法默認仍是進行四個參數的哈希運算,計算出的兩個對象的若是id和name相同,author或者price不一樣也會計算出不一樣的hashcode。這樣的話咱們自定義的兩個相同的對象都能成功加入hashset,違背原則,因此必須同時覆蓋這兩個方法。
Book1 b1 = new Book1(1, "hh", "zs", 122.0); Book1 b2 = new Book1(1, "hh", "zh", 112.0);
這兩個對象只能加進去一個到HashSet中