我正在尝试编写一个服务器,它使用一个唯一生成的 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 方法根本不像我想要的那样工作它到);我该如何解决这个问题?