我正在尝试编写一个服务器,它使用一个唯一生成的 ID 来跟踪它的客户端HashMap<ClientID,Client>
。这个想法是,如果我是管理员并且我想将某人从服务器上启动,我会查找适当的 ClientID(这实际上只是一个字符串;唯一的区别是 ClientID 类的工作是确保没有两个客户端是曾经为该客户端分配了相同的 ID),然后输入诸如“kick 12”之类的命令(如果我想踢的人的 ClientID 恰好是 12)。我认为这会起作用,因为我认为HashMap
可能是由从 Object 继承的 hashCode() 方法的内部使用支持的,并且我以支持必要查找操作的方式设计了 ClientID 类,假设这是真的。但显然,这不是真的 - 具有相同哈希码的两个键显然不被认为是 a HashMap
(or HashSet
) 中的相同键。我创建了一个简单的示例HashSet
来说明我想要做什么:
导入java.lang.*; 导入java.io.*; 导入 java.util.*; 类客户 ID { 私有字符串 id; 公共客户端 ID(字符串 myId) { 身份证=我的身份证; } 公共静态 ClientID generateNew(Set<ClientID> 存在) { ClientID res = new ClientID(""); 随机 rand = new Random(); 做 { int p = rand.nextInt(10); res.id += p; } 而 (existing.contains(res)); 返回资源; } 公共 int hashCode() { 返回(id.hashCode()); } 公共布尔等于(字符串 otherID) { 返回(id == otherID); } 公共布尔等于(ClientID 其他) { 返回(id == other.id); } 公共字符串 toString() { 返回标识; } 公共静态 void main(String[] args) 抛出 IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); HashSet<ClientID> mySet = new HashSet<ClientID>(); ClientID myId = ClientID.generateNew(mySet); mySet.add(myId); 字符串输入; 做 { System.out.println("集合中的ID/哈希码列表:"); for (ClientID x: mySet) System.out.println("\t" + x.toString() + "\t" + x.hashCode()); System.out.print("\n输入一个ID来测试它是否在集合中:"); 输入 = in.readLine(); 如果(输入==空) 休息; 否则 if (input.length() == 0) 继续; ClientID matchID = new ClientID(input); if (mySet.contains(matchID)) System.out.println("成功!Set 已经包含该 ID :)"); 别的 { System.out.println("添加ID " + matchID.toString() + " (hashcode " + matchID.hashCode() + ") 到集合"); mySet.add(matchID); } System.out.println("\n"); } while (!input.toUpperCase().equals("QUIT")); } }
使用此代码,(据我所知)不可能产生输出
成功!Set 已经包含该 ID :)
...相反,它只会继续向该集合添加值,即使这些值是重复的(也就是说,它们与 equals 方法相等并且它们具有相同的哈希码)。如果我没有很好地沟通,请自己运行代码,我想你会很快明白我的意思......这使得查找变得不可能(这也意味着 Client.generateNew 方法根本不像我想要的那样工作它到);我该如何解决这个问题?