为什么自定义对象不是 HashMap 的等效键?
我在使用自己的类作为 HashMap 的键时遇到问题
I'm having trouble using my own class as a key for a HashMap
public class ActorId {
private final int playerId;
private final int id;
ActorId(int playerId, int id) {
this.playerId = playerId;
this.id = id;
}
public boolean equals(ActorId other) {
return this.id == other.id && this.playerId == other.playerId;
}
public int hashCode() {
int hash = 1;
hash = hash * 31 + playerId;
hash = hash * 31 + id;
return hash;
}
public String toString() {
return "#" + playerId + "." + id;
}
public int getPlayerId() {
return playerId;
}
}
这是一个失败的 JUnit 测试
Here is a failing JUnit test
import static org.junit.Assert.*;
import java.util.Map;
import org.junit.Test;
public class ActorIdTest {
@Test
public final void testAsMapKey() {
ActorId a = new ActorId(123, 345);
ActorId b = new ActorId(123, 345);
assertTrue(a.equals(b));
assertEquals(a.hashCode(), b.hashCode());
// Works with strings as keys
Map<String, String> map1 = new java.util.HashMap<String, String>();
map1.put(a.toString(), "test");
assertEquals("test", map1.get(a.toString()));
assertEquals("test", map1.get(b.toString()));
assertEquals(1, map1.size());
// But not with ActorIds
Map<ActorId, String> map2 = new java.util.HashMap<ActorId, String>();
map2.put(a, "test");
assertEquals("test", map2.get(a));
assertEquals("test", map2.get(b)); // FAILS here
assertEquals(1, map2.size());
map2.put(b, "test2");
assertEquals(1, map2.size());
assertEquals("test2", map2.get(a));
assertEquals("test2", map2.get(b));
}
}
推荐答案
你需要改变
public boolean equals(ActorId other) {
....
}
到
public boolean equals(Object other) {
....
}
<小时>
每日提示:始终使用 @Override
注释.
如果你使用了 @Override
注释,编译器会捕捉到错误并说:
If you had used the @Override
annotation, the compiler would have caught the error and said:
ActorId 类型的方法 equals(ActorId) 必须重写或实现超类型方法
The method equals(ActorId) of type ActorId must override or implement a supertype method
相关文章