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()
Entry[]
(Entry是一种LinkedList) "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
的步骤(如果两个实例不同)