gpt4 book ai didi

java - 为什么我在 Java HashMap 中得到重复的键?

转载 作者:IT老高 更新时间:2023-10-28 20:56:38 26 4
gpt4 key购买 nike

我似乎在标准 Java HashMap 中得到了重复的键。通过“重复”,我的意思是键通过它们的 equals() 方法相等。这是有问题的代码:

import java.util.Map;
import java.util.HashMap;

public class User {
private String userId;
public User(String userId) {
this.userId = userId;
}
public boolean equals(User other) {
return userId.equals(other.getUserId());
}
public int hashCode() {
return userId.hashCode();
}
public String toString() {
return userId;
}

public static void main(String[] args) {
User arvo1 = new User("Arvo-Part");
User arvo2 = new User("Arvo-Part");
Map<User,Integer> map = new HashMap<User,Integer>();
map.put(arvo1,1);
map.put(arvo2,2);

System.out.println("arvo1.equals(arvo2): " + arvo1.equals(arvo2));
System.out.println("map: " + map.toString());
System.out.println("arvo1 hash: " + arvo1.hashCode());
System.out.println("arvo2 hash: " + arvo2.hashCode());
System.out.println("map.get(arvo1): " + map.get(arvo1));
System.out.println("map.get(arvo2): " + map.get(arvo2));
System.out.println("map.get(arvo2): " + map.get(arvo2));
System.out.println("map.get(arvo1): " + map.get(arvo1));
}
}

这是结果输出:

arvo1.equals(arvo2): true
map: {Arvo-Part=1, Arvo-Part=2}
arvo1 hash: 164585782
arvo2 hash: 164585782
map.get(arvo1): 1
map.get(arvo2): 2
map.get(arvo2): 2
map.get(arvo1): 1

如您所见,两个 User 对象的 equals() 方法返回 true 并且它们的哈希码相同,然而它们各自在 map 中形成一个不同的 key。此外,map 继续区分最后四个 get() 调用中的两个 User 键。

这与 documentation 直接矛盾。 :

More formally, if this map contains a mapping from a key k to a value v such that (key==null ? k==null : key.equals(k)), then this method returns v; otherwise it returns null. (There can be at most one such mapping.)

这是一个错误吗?我在这里错过了什么吗?我正在运行通过 Homebrew 安装的 Java 版本 1.8.0_92。

编辑:该问题已被标记为与 other question 重复,但我将保留这个问题,因为它识别出与 equals() 的看似不一致,而另一个问题假定错误在于 hashCode()。希望这个问题的存在将使这个问题更容易搜索。

最佳答案

问题在于您的 equals() 方法。 Object.equals() 的签名是 equals(OBJECT),但在你的情况下它是 equals(USER),所以这是两个完全不同的方法,hashmap 调用带有 Object 参数的方法。您可以通过将 @Override 注释放在等号上来验证这一点 - 它会生成编译器错误。

equals方法应该是:

  @Override
public boolean equals(Object other) {
if(other instanceof User){
User user = (User) other;
return userId.equals(user.userId);
}

return false;
}

作为最佳实践,您应该始终将 @Override 放在您覆盖的方法上 - 它可以为您省去很多麻烦。

关于java - 为什么我在 Java HashMap 中得到重复的键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38388751/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com