@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存储过。