Mi sembra di avere chiavi duplicate nella HashMap standard di Java. Per "duplicato", intendo che i tasti sono uguali per il loro metodo equals()
. Ecco il codice problematico:Perché sto ottenendo chiavi duplicate in Java HashMap?
import java.util.Map;
import java.util.HashMap;
public class User {
private String userId;
public User(String userId) {
this.userId = userId;
}
public boolean equals(User other) {
return userId.equals(other.getUserId());
}
public int hashCode() {
return userId.hashCode();
}
public String toString() {
return userId;
}
public static void main(String[] args) {
User arvo1 = new User("Arvo-Part");
User arvo2 = new User("Arvo-Part");
Map<User,Integer> map = new HashMap<User,Integer>();
map.put(arvo1,1);
map.put(arvo2,2);
System.out.println("arvo1.equals(arvo2): " + arvo1.equals(arvo2));
System.out.println("map: " + map.toString());
System.out.println("arvo1 hash: " + arvo1.hashCode());
System.out.println("arvo2 hash: " + arvo2.hashCode());
System.out.println("map.get(arvo1): " + map.get(arvo1));
System.out.println("map.get(arvo2): " + map.get(arvo2));
System.out.println("map.get(arvo2): " + map.get(arvo2));
System.out.println("map.get(arvo1): " + map.get(arvo1));
}
}
Ed ecco l'output risultante:
arvo1.equals(arvo2): true
map: {Arvo-Part=1, Arvo-Part=2}
arvo1 hash: 164585782
arvo2 hash: 164585782
map.get(arvo1): 1
map.get(arvo2): 2
map.get(arvo2): 2
map.get(arvo1): 1
Come si può vedere, il metodo equals()
sui due User
oggetti sta tornando true
ed i loro codici hash sono gli stessi , tuttavia ognuno di essi forma uno key
distinto in map
. Inoltre, map
continua a distinguere tra le due chiavi User
nelle ultime quattro chiamate get()
.
Questo contraddice direttamente la documentation:
Più formalmente, se questa mappa contiene una mappatura da una chiave k ad un valore tale che v (tasto == null k == null:? Key.equals (k)), quindi questo metodo restituisce v; altrimenti restituisce null. (Ci può essere al massimo una tale mappatura.)
Si tratta di un errore? Mi sto perdendo qualcosa qui? Sto eseguendo la versione 1.8.0_92 di Java, che ho installato tramite Homebrew.
EDIT: Questa domanda è stato contrassegnato come un duplicato di questo other question, ma lascio questa domanda è perché identifica un'incongruenza apparente con equals()
, mentre l'altra questione assume l'errore si trova con hashCode()
. Speriamo che la presenza di questa domanda renda la ricerca più facile.
Prova ad aggiungere '@ Override' al vostro' equals' e metodi 'hashCode' (sempre una best practice) e vedere se si ottengono informazioni utili. – chrylis
Per consentire questo tipo di errori di battitura, o errori, in futuro, lasciare sempre che l'IDE generi i metodi per te. Quindi modificali per farli apparire come desideri. Questo avrebbe creato i metodi corretti con annotazioni '@ Override'. – Magnilex