廢話不多說,先上案例,如下
先定義一個User類,並定義2個屬性,構造方法,new 2個對象,user1 user2
public static void main(String[] args) { User user1 = new User(1,"張三"); User user2 = new User(1,"張三"); System.out.println(user1.hashCode()); System.out.println(user2.hashCode()); System.out.println(user1.equals(user2)); Set<User> set = new HashSet<User>(); set.add(user1); set.add(user2); System.out.println(set); }
運行程序,輸出結果如下:
重寫 hashcode 和 equals 重新運行,結果如下:
2張運行結果可以看出hashcode 值相等,且 equals 返回 true HashSet 起到去重效果
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (age != user.age) return false; return name.equals(user.name); } @Override public int hashCode() { int result = age; result = 31 * result + name.hashCode(); return result; }
以下是關於hashcode的一些規定:
兩個對象相等,hashcode一定相等,兩個對象不等,hashcode不一定不等;
hashcode相等,兩個對象不一定相等,hashcode不等,兩個對象一定不等;
以下是Object源碼中hashcode 和 equals的具體實現
public native int hashCode(); public boolean equals(Object obj) { return (this == obj); }
不重寫 hashcode 和 equals 的情況,默認使用Object內中的 equals 和hashcode方法
默認情況下Object 為不同對象生成的 hashcode 一般是不同的,默認equals 方法比較的是2個對象的內存地址,所以比較結果為false
我們只重新hashcode方法,不重新equals 方法,運行程序結果如下:
雖然hashcode值相同,但是比較的任然是內存地址,然而2個對象的內存地址是不一樣的,所以比較結果任然是false,只有同時重新hashcode 和equals 才能判讀2個對象是否相等,才能達到去重效果;
注意:==比較的是內存地址, equals比較的是值是否相等