【发布时间】:2023-03-29 15:59:02
【问题描述】:
我似乎在标准 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直接矛盾:
更正式地说,如果此映射包含从键 k 到值 v 的映射,满足 (key==null ? k==null : key.equals(k)),则此方法返回 v;否则返回null。 (最多可以有一个这样的映射。)
这是一个错误吗?我在这里错过了什么吗?我正在运行通过 Homebrew 安装的 Java 版本 1.8.0_92。
编辑:此问题已被标记为此other question 的重复,但我将保留此问题,因为它识别出与equals() 的看似不一致,而另一个问题假定错误在于@987654335 @。希望这个问题的存在将使这个问题更容易搜索。
【问题讨论】:
-
尝试将
@Override添加到您的equals和hashCode方法中(始终是最佳实践),看看是否能获得任何有用的信息。 -
为了允许这种错别字或错误,以后总是让你的IDE为你生成方法。然后调整它们,使它们看起来像你想要的。这将使用
@Override注释创建正确的方法。
标签: java hashmap equals hashcode