Java集合:如果Hashmap的键是不可变对象,那么我们需要重写hashcode和equals吗?

Java集合:如果Hashmap的键是不可变对象,那么我们需要重写hashcode和equals吗?,java,collections,hashmap,equals,hashcode,Java,Collections,Hashmap,Equals,Hashcode,我对一个概念感到困惑。谁能帮我照一下吗 问题:如果Hashmap的键是不可变对象(由开发人员创建),那么我们是否需要重写hashcode()和equals()?或者将不可变字段作为键解决了重写hashcode()和equals()的问题 谢谢。是的。这里我将引用java.lang.Integer的例子。如果我们希望有一个整数到对象的(稀疏)映射,我们将使用类似于HashMap的HashMap。如果我们添加一个条目Integer.valueOf(2)=>“foo”,并尝试使用新整数(2)检索它,则

我对一个概念感到困惑。谁能帮我照一下吗

问题:如果
Hashmap
的键是不可变对象(由开发人员创建),那么我们是否需要重写
hashcode()
equals()
?或者将不可变字段作为键解决了重写
hashcode()
equals()
的问题


谢谢。

是的。这里我将引用
java.lang.Integer
的例子。如果我们希望有一个整数到对象的(稀疏)映射,我们将使用类似于HashMap的
HashMap
。如果我们添加一个条目
Integer.valueOf(2)=>“foo”
,并尝试使用
新整数(2)
检索它,则需要重写的hashcode和equals。

是。这里我将引用
java.lang.Integer
的例子。如果我们希望有一个整数到对象的(稀疏)映射,我们将使用类似于HashMap的
HashMap
。如果我们添加一个条目
Integer.valueOf(2)=>“foo”
,并尝试使用
newinteger(2)
检索它,则需要重写的hashcode和equals。

请尝试并查看:

public class OverrideIt
{
    static class MyKey
    {
        public final int i; // immutable
        public MyKey(int i)
        {
            this.i = i;
        }
    }

    public static void main(String[] args)
    {
        Map<MyKey, String> map = new HashMap<MyKey, String>();
        map.put(new MyKey(1), "Value");
        String result = map.get(new MyKey(1));
        System.out.println(result);  // null
    }
}
公共类重写EIT
{
静态类MyKey
{
公共final int i;//不可变
公钥(int i)
{
这个。i=i;
}
}
公共静态void main(字符串[]args)
{
Map Map=newhashmap();
map.put(新的MyKey(1),“值”);
stringresult=map.get(newmykey(1));
System.out.println(结果);//null
}
}
它打印出
null
,表明我们无法查找值。这是因为
MyKey
的两个副本不相等,并且没有相同的hashcode,因为我们没有覆盖
.equals()
hashcode()
试试看:

public class OverrideIt
{
    static class MyKey
    {
        public final int i; // immutable
        public MyKey(int i)
        {
            this.i = i;
        }
    }

    public static void main(String[] args)
    {
        Map<MyKey, String> map = new HashMap<MyKey, String>();
        map.put(new MyKey(1), "Value");
        String result = map.get(new MyKey(1));
        System.out.println(result);  // null
    }
}
公共类重写EIT
{
静态类MyKey
{
公共final int i;//不可变
公钥(int i)
{
这个。i=i;
}
}
公共静态void main(字符串[]args)
{
Map Map=newhashmap();
map.put(新的MyKey(1),“值”);
stringresult=map.get(newmykey(1));
System.out.println(结果);//null
}
}
它打印出
null
,表明我们无法查找值。这是因为
MyKey
的两个副本不相等,并且没有相同的hashcode,因为我们没有覆盖
.equals()
hashcode()

  • hashMap的基本数据结构是
    Entry[]
    (Entry是一种LinkedList)
  • 键的哈希代码,用于定位此数组中的位置
  • 使用hashcode重试条目后,将使用Key的Equal来选择正确的条目(通过迭代hasNext)
  • 默认哈希代码返回该实例的唯一整数值
  • 你在评论部分同意了吗

     "Is it possible that you'll store an object using one key, 
      and then try to retrieve it using a key which is an identical object,
      but not the same object"
    
    即使两个键具有相同的值,实例也不同。然后,根据合同(事实4),两个键可能有不同的哈希代码。因此,您将在数组中有不同的位置(规则2)

    map.put(新键(1),“第一个元素”)

    在这里,键对象不重写,所以它将返回每个实例的hashcode unquie。(为了避免太复杂,假设hashcode返回为000025。因此条目[25]是“第一个元素”)

    map.get(新键(1))

    现在,这个新键可能返回hashcode值为
    000017
    ,因此它将尝试从条目[17]中获取值并返回null(不例外)

    注意:为了简单起见,我刚刚给出了样本000025和000017,实际上hashmap将重新访问hashcode并根据数组大小对其进行更改

    到目前为止,我们还没有讨论密钥是可变的还是不变的。不管密钥是可变的还是不可变的

    If you store an object using one key,and then try to retrieve it using a key 
    which is an identical object,but not the same object
    
    您需要重写hashcode并确保它返回相同的整数,这样它将定位相同的bucket(数组中的位置)并获取元素。这同样适用于equals,以便从条目中获取正确的元素

  • hashMap的基本数据结构是
    Entry[]
    (Entry是一种LinkedList)
  • 键的哈希代码,用于定位此数组中的位置
  • 使用hashcode重试条目后,将使用Key的Equal来选择正确的条目(通过迭代hasNext)
  • 默认哈希代码返回该实例的唯一整数值
  • 你在评论部分同意了吗

     "Is it possible that you'll store an object using one key, 
      and then try to retrieve it using a key which is an identical object,
      but not the same object"
    
    即使两个键具有相同的值,实例也不同。然后,根据合同(事实4),两个键可能有不同的哈希代码。因此,您将在数组中有不同的位置(规则2)

    map.put(新键(1),“第一个元素”)

    在这里,键对象不重写,所以它将返回每个实例的hashcode unquie。(为了避免太复杂,假设hashcode返回为000025。因此条目[25]是“第一个元素”)

    map.get(新键(1))

    现在,这个新键可能返回hashcode值为
    000017
    ,因此它将尝试从条目[17]中获取值并返回null(不例外)

    注意:为了简单起见,我刚刚给出了样本000025和000017,实际上hashmap将重新访问hashcode并根据数组大小对其进行更改

    到目前为止,我们还没有讨论密钥是可变的还是不变的。不管密钥是可变的还是不可变的

    If you store an object using one key,and then try to retrieve it using a key 
    which is an identical object,but not the same object
    

    您需要重写hashcode并确保它返回相同的整数,这样它将定位相同的bucket(数组中的位置)并获取元素。同样适用于从条目中获取正确元素的equals。这些问题的类别略有不同

    与中一样,拥有不可变实例不足以让您跳过编写
    equals
    hashCode
    的步骤(如果两个实例不同)