为什么自定义对象不是HashMap的等效键? [英] Why are custom objects not equivalent keys for a HashMap?
本文介绍了为什么自定义对象不是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;
返回哈希;
}
public String toString(){
return#+ playerId +。 + id;
}
public int getPlayerId(){
return playerId;
}
}
这是一个失败的JUnit测试
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());
//使用字符串作为键
映射< 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());
//但不是与ActorIds
映射< 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){
....
}
< hr>
提示:始终使用 @Override
注释。
如果您使用了 @Override
注释,编译器将会收到错误并说:
类型ActorId的方法equals(ActorId)必须覆盖或实现超类型方法
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;
}
}
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));
}
}
解决方案
You need to change
public boolean equals(ActorId other) {
....
}
to
public boolean equals(Object other) {
....
}
Tip of the day: Always use @Override
annotation.
If you had used the @Override
annotation, the compiler would have caught the error and said:
The method equals(ActorId) of type ActorId must override or implement a supertype method
这篇关于为什么自定义对象不是HashMap的等效键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文