为什么自定义对象不是 HashMap 的等效键?

Why are custom objects not equivalent keys for a HashMap?(为什么自定义对象不是 HashMap 的等效键?)
本文介绍了为什么自定义对象不是 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

这篇关于为什么自定义对象不是 HashMap 的等效键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Show progress during FTP file upload in a java applet(在 Java 小程序中显示 FTP 文件上传期间的进度)
How to copy a file on the FTP server to a directory on the same server in Java?(java - 如何将FTP服务器上的文件复制到Java中同一服务器上的目录?)
FTP zip upload is corrupted sometimes(FTP zip 上传有时会损坏)
Enable logging in Apache Commons Net for FTP protocol(在 Apache Commons Net 中为 FTP 协议启用日志记录)
Checking file existence on FTP server(检查 FTP 服务器上的文件是否存在)
FtpClient storeFile always return False(FtpClient storeFile 总是返回 False)