Кажется, я получаю дубликаты ключей в стандартном Java HashMap. Под "duplicate" я подразумеваю, что ключи равны их методу equals()
. Вот проблематичный код:
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));
}
}
И вот результат:
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
Как вы можете видеть, метод equals()
для двух объектов User
возвращает true
, а их хэш-коды одинаковы, но каждый из них образует отдельный key
в map
. Кроме того, map
продолжает различать две клавиши User
в последних четырех вызовах get()
.
Это прямо противоречит документации:
Более формально, если эта карта содержит отображение из ключа k в значение v, такое что (ключ == null? k == null: key.equals(k)), то этот метод возвращает v; в противном случае он возвращает null. (Это может быть не более одного такого отображения.)
Это ошибка? Я что-то упустил? Я запускаю Java версию 1.8.0_92, которую я установил через Homebrew.
EDIT: этот вопрос был отмечен как дубликат этого другого вопроса, но я оставлю этот вопрос так же, как и потому, что он идентифицирует кажущуюся несогласованность с equals()
, тогда как другой вопрос предполагает, что ошибка лежит в hashCode()
. Надеемся, что наличие этого вопроса сделает эту проблему более удобной для поиска.