0
点赞
收藏
分享

微信扫一扫

重写equals方法的时候为什么需要重写hashCode


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

 

Reference

  • ​​重写equals方法的时候为什么需要重写hashcode​​


举报

相关推荐

0 条评论