【问题标题】:Java HashMap return value not confirming with my understanding of equals and hashcodeJava HashMap返回值与我对equals和hashcode的理解不一致
【发布时间】:2014-11-26 10:57:24
【问题描述】:

以下代码示例的输出为:

{1--e=e2, 2--e1=e1}

package com.sid.practice;

import java.util.HashMap;
import java.util.Map;

public class InputOutputPractice 
{

    public InputOutputPractice() 
    {

    }

    public static void main(String[] args) 
    {
        Employee e = new InputOutputPractice().new Employee(1, "e");
        Employee e1 = new InputOutputPractice().new Employee(2, "e1");
        Employee e2 = new InputOutputPractice().new Employee(1, "e2");

        Map m = new HashMap();
        m.put(e, "e");
        m.put(e1, "e1");
        m.put(e2, "e2");
        System.out.println(m);

    }

    class Employee
    {
        public Employee(int id, String name)
        {
            this.id=id;
            this.name = name;
        }

        private int id;
        private String name;

        public String getName() 
        {
            return name;
        }

        public void setName(String name) 
        {
            this.name = name;
        }

        public int getId() 
        {
            return id;
        }

        public void setId(int id) 
        {
            this.id = id;
        }

        @Override
        public boolean equals(Object obj) 
        {
            return ((Employee)obj).getId()==(this.getId());
        }

        @Override
        public int hashCode() 
        {
            return Integer.valueOf(getId()).hashCode();
        }

        @Override
        public String toString() 
        {
            return this.id + "--" + this.name;
        }
    }
}

我不明白对象e2 是如何覆盖对象e 中的键,而不是值。据我了解,输出应该是:

{1--e2=e2, 2--e1=e1}

【问题讨论】:

    标签: java hashmap equals hashcode


    【解决方案1】:

    实际上,你把它弄反了。该值已被覆盖。密钥没有被替换,因为就HashMap 而言,e 和 e2 是相同的。

    你的输出是{1--e=e2, 2--e1=e1}

    key = e, value = "e2" (which overrode the old value "e")
    key = e1, value = "e1" 
    

    【讨论】:

    • 有道理,我原以为整个对象都被覆盖了。
    【解决方案2】:

    put 方法的 HashMap 状态的Javadocs

    将指定的值与此映射中的指定键相关联。如果映射先前包含键的映射,则替换旧值。

    因此,键没有被覆盖,只有值。

    【讨论】:

    • 我以为整个对象都被覆盖了。
    • 但是在 Maps 的情况下,有两个对象:一个键和一个值。假设密钥的 hashCode 唯一标识密钥,因此覆盖它没有意义。所以只有值被覆盖。
    【解决方案3】:

    当现有键与 put() 调用中提供的键相等时,java.util.HashMap 实现不会替换现有键。因此,您的第三个 put() 检查地图的现有内容,找到现有的相等键并更新关联的值。

    这说明了为什么 equals() 和 hashCode() 通常应该考虑所有属性,因为被认为相等的对象被许多 util 类认为是可互换的。

    【讨论】:

      【解决方案4】:

      输出 {1--e=e2, 2--e1=e1} 背后的原因是:

      Map 不会替换键,它仅在现有 Map 中存在匹配项(基于键存在)时才会替换值。 所以适用于这种情况:

      这里 e 等于 Map 的 e2。当 Map 搜索要放置的位置时 m.put(e2, "e2");它转到存在 e--"e1" 的位置并将 "e1" 替换为 "e2" 并保留密钥,即在本例中的 e 完整

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-22
        • 2021-10-31
        • 2016-05-23
        • 2010-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多