Я пытаюсь написать сервер, который отслеживает своих клиентов по уникальному идентификатору, сгенерированному с использованием HashMap
. Идея состоит в том, что если я администратор и хочу загрузить кого-то с сервера, я ищу соответствующий ClientID (который на самом деле является просто строкой; единственная разница в том, что класс ClientID выполняет работу по обеспечению того, чтобы никакие два клиента не когда-либо назначал один и тот же идентификатор) для этого клиента, а затем введите команду, например, «kick 12» (если ClientID человека, которого я хотел исключить, оказался равным 12).
Я предположил, что это сработает, потому что полагал, что HashMap
, вероятно, поддерживается внутренним использованием метода hashCode(), унаследованного от Object, и я разработал класс ClientID таким образом, чтобы он поддерживал необходимые операции поиска, если это правда. Но, видимо, это не так — два ключа с одинаковыми хэш-кодами явно не считаются одним и тем же ключом в HashMap
(или HashSet
).
Я создал простой пример, используя HashSet
, чтобы проиллюстрировать, что я хочу сделать:
import java.lang.*; import java.io.*; import java.util.*; class ClientID { private String id; public ClientID(String myId) { id = myId; } public static ClientID generateNew(Set<ClientID> existing) { ClientID res = new ClientID(""); Random rand = new Random(); do { int p = rand.nextInt(10); res.id += p; } while (existing.contains(res)); return res; } public int hashCode() { return (id.hashCode()); } public boolean equals(String otherID) { return (id == otherID); } public boolean equals(ClientID other) { return (id == other.id); } public String toString() { return id; } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); HashSet<ClientID> mySet = new HashSet<ClientID>(); ClientID myId = ClientID.generateNew(mySet); mySet.add(myId); String input; do { System.out.println("List of IDs/hashcodes in the set: "); for (ClientID x: mySet) System.out.println("\t" + x.toString() + "\t" + x.hashCode()); System.out.print("\nEnter an ID to test if it's in the set: "); input = in.readLine(); if (input == null) break; else if (input.length() == 0) continue; ClientID matchID = new ClientID(input); if (mySet.contains(matchID)) System.out.println("Success! Set already contains that ID :)"); else { System.out.println("Adding ID " + matchID.toString() + " (hashcode " + matchID.hashCode() + ") to the set"); mySet.add(matchID); } System.out.println("\n"); } while (!input.toUpperCase().equals("QUIT")); } }
Используя этот код, невозможно (насколько я могу судить) произвести вывод
Success! Set already contains that ID :)
... Вместо этого он просто продолжит добавлять значения в этот набор, даже если значения дублируются (то есть они равны с методом equals И имеют одинаковый хэш-код).Если я не доношу это правильно, запустите код для себя, и я думаю, вы быстро поймете, что я имею в виду... Это делает поиск невозможным (и это также означает, что метод Client.generateNew НЕ работает вообще, как я предполагал это к); как это обойти?