@AllArgsConstructor
public class Pairs {
@Getter
@Setter
private String key;
@Getter
@Setter
private String value;
}
public static void main(String[] args) {
Pairs pairs1 = new Pairs("name", "zhangsan");
Pairs pairs2 = new Pairs("name", "zhangsan");
System.out.println(pairs1.hashCode());
System.out.println(pairs2.hashCode());
System.out.println(pairs1.equals(pairs2));
Map<Pairs, String> pairsMap = Maps.newHashMap();
pairsMap.put(pairs1, pairs1.getValue());
pairsMap.put(pairs2, pairs2.getValue());
System.out.println(pairsMap.size());
}
程序運行結果
1221555852
1509514333
false
2
只重寫equals 不重寫hashCode
@AllArgsConstructor
public class Pairs {
@Getter
@Setter
private String key;
@Getter
@Setter
private String value;
@Override
public boolean equals(final Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof Pairs) {
Pairs pairs = (Pairs) obj;
// 比較各個屬性
if (pairs.key.equals(key)
&& pairs.value.equals(value)) {
return true;
}
return false;
}
return false;
}
}
程序運行結果
1221555852
1509514333
true
2
Map中存了兩個數值一樣的key,這個問題很嚴重。所以在重寫equals方法的時候,一定要重寫hashCode方法。
類似HashMap、HashTable、HashSet這種的都要考慮到散列的數據類型的運用。
既重寫equals又重寫hashCode
@AllArgsConstructor
public class Pairs {
@Getter
@Setter
private String key;
@Getter
@Setter
private String value;
@Override
public boolean equals(final Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof Pairs) {
Pairs pairs = (Pairs) obj;
// 比較各個屬性
if (pairs.key.equals(key) && pairs.value.equals(value)) {
return true;
}
return false;
}
return false;
}
@Override
public int hashCode() {
int result = 1;
result = 24 * result +
((this.key == null) ?
1 : this.key.hashCode());
result = 24 * result +
((this.value == null) ?
1 : this.value.hashCode());
return result;
}
}
程序運行結果
-1351635012
-1351635012
true
1
重寫了equals方法, 必須要重寫hashCode
對於兩個對象
- hashCode() 值相同, equals() 不一定相同
- equals() 相同, hashCode() 值一定相同
HashMap 存儲數據的時候,是取的 key 值的哈希值, 然後計算數組下標, 採用鏈地址法解決衝突, 然後進行存儲。 取數據的時候, 依然是先要獲取到哈希值, 找到數組下標, 然後 for 遍歷鏈表集合, 進行比較是否有對應的key。 比較關心的有兩點:
- 無論是 put 還是 get 的時候, 都需要得到 key 的哈希值, 去定位 key 的數組下標;
- 在 get 的時候, 需要調用 equals 方法比較是否有相等的key存儲過。