为什么自定义对象不是HashMap的等效键? [英] Why are custom objects not equivalent keys for a HashMap?

查看:172
本文介绍了为什么自定义对象不是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆