java - 以对象列表为键的 HashMap

标签 java collections hashmap equals hashcode

在 HashMap 中,当我将对象列表作为键传递时,我得到了不同的结果。

List<NewClass> list1 = new ArrayList<>();
List<NewClass> list2 = new ArrayList<>();

NewClass obj1 = new NewClass(1, "ddd", "eee@gmail.com");
NewClass obj2 = new NewClass(2, "ccc", "kkk@gmail.com");

list1.add(obj1);
list1.add(obj2);

list2.add(obj1);
list2.add(obj2);

Map<List<NewClass>, Integer> mapClass = new HashMap<>();
mapClass.put(list1, 1234);
mapClass.put(list2, 4567);

System.out.println(mapClass.size());
System.out.println(mapClass.get(list1));

NewClass obj4 = new NewClass(1, "ddd", "eee@gmail.com");
NewClass obj5 = new NewClass(2, "ccc", "kkk@gmail.com");
List<NewClass> list3 = new ArrayList<>();
list3.add(obj4);
list3.add(obj5);

System.out.println(mapClass.get(list3));

System.out.println(list1.hashCode());
System.out.println(list2.hashCode());
System.out.println(list3.hashCode());

下面是我看到的输出

hashCode() called - Computed hash: -1704251796
hashCode() called - Computed hash: -587009612
hashCode() called - Computed hash: -1704251796
hashCode() called - Computed hash: -587009612
1
hashCode() called - Computed hash: -1704251796
hashCode() called - Computed hash: -587009612
4567
hashCode() called - Computed hash: -1704251796
hashCode() called - Computed hash: -587009612
**null**
hashCode() called - Computed hash: -1704251796
hashCode() called - Computed hash: -587009612
-1879206775
hashCode() called - Computed hash: -1704251796
hashCode() called - Computed hash: -587009612
-1879206775
hashCode() called - Computed hash: -1704251796
hashCode() called - Computed hash: -587009612
-1879206775

尽管所有 3 个列表的哈希码都相同,但 mapClass.get(list3) 正在重新调整为 null。 list3 与 list1/list2 具有相同的对象。为什么会出现这种行为?

最佳答案

来自 map V get(Object key) 文档:

 * ... if this map contains a mapping from a key
 * {@code k} to a value {@code v} such that
 * {@code Objects.equals(key, k)},
 * then this method returns {@code v}; otherwise
 * it returns {@code null}. ...

我不确定你是如何实现 NewClassequals 方法的,但是 NewClass 的以下实现不会返回 null 当调用 System.out.println(mapClass.get(list3));

public class NewClass {
    private int id;
    private String name;
    private String mail;

    NewClass(int id,String name,String mail){
        this.id = id;
        this.name = name;
        this.mail = mail;
    }

    @Override
    public int hashCode() {
        return id * name.hashCode() * mail.hashCode();
    }

    @Override
    public boolean equals(Object o) {

        if (o == this) return true;
        if (!(o instanceof NewClass)) {
            return false;
        }
        NewClass newClass = (NewClass) o;

        return newClass.id == id &&
               newClass.name.equals(name) &&
               newClass.mail.equals(mail);
    }
}

此外,正如评论中提到的可变键不是一个好主意,请检查 this link其中详细说明了原因。

关于java - 以对象列表为键的 HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71853303/

相关文章:

java - hashmap 包含键复杂度

dictionary - map 中的最大元素数

java - 使用 Mina 模拟 XMPP 服务器仅在部分时间有效

java - 如何从这两个数组生成一组指定数量的数字?

java - 通用字符串java的多序列比对

Java 集合排序。应先大写,后小写

java - 尝试在 JDBC 数据源上启用 Oracle 透明数据加密

java - Java 中的 IEqualityComparer 接口(interface)

java - 允许多种预定义类型的集合

javascript - 是否有用于 JavaScript 的 hashmap 库?