Java hashmap在调用containsKey()时检查什么? ArrayList lis=new ArrayList(); 增加(2); 增加(3); ArrayList lis2=新的ArrayList(); lis2.添加(2); lis2.添加(3); HashMap=newHashMap(); 地图放置(lis,7); System.out.println(map.containsKey(lis2));
最初,我希望代码打印出“false”,因为lis和lis2是不同的对象。Java hashmap在调用containsKey()时检查什么? ArrayList lis=new ArrayList(); 增加(2); 增加(3); ArrayList lis2=新的ArrayList(); lis2.添加(2); lis2.添加(3); HashMap=newHashMap(); 地图放置(lis,7); System.out.println(map.containsKey(lis2));,java,hashmap,hashtable,containskey,Java,Hashmap,Hashtable,Containskey,最初,我希望代码打印出“false”,因为lis和lis2是不同的对象。 令人惊讶的是,代码打印出“true”。hashmap在调用containsKey()时检查什么?它检查.hashCode以找到bucket,然后使用.equalsList.equals返回true如果所有元素的顺序相同并且也是.equalsArrayList.hashCode将为具有相同元素的两个ArrayList实例返回相同的值,因此它会找到正确的bucket,然后使用.equals并查看列表的元素是否相同且顺序相同 例
令人惊讶的是,代码打印出“true”。hashmap在调用containsKey()时检查什么?它检查
.hashCode
以找到bucket,然后使用.equals
List.equals
返回true
如果所有元素的顺序相同并且也是.equals
ArrayList.hashCode
将为具有相同元素的两个ArrayList
实例返回相同的值,因此它会找到正确的bucket,然后使用.equals
并查看列表的元素是否相同且顺序相同
例如:
ArrayList<Integer> lis = new ArrayList<Integer>();
lis.add(2);
lis.add(3);
ArrayList<Integer> lis2 = new ArrayList<Integer>();
lis2.add(2);
lis2.add(3);
HashMap<ArrayList<Integer>, Integer> map = new HashMap<ArrayList<Integer>, Integer>();
map.put(lis, 7);
System.out.println(map.containsKey(lis2));
这是因为添加另一个元素更改了lis.hashCode()
的值。当您put
列表时,使用hashCode
拾取一个bucket。通过添加新元素,您可以更改它将使用的bucket,但不会更改您已经添加到地图中的条目的bucket。除此之外:
map.put(lis, 7);
lis.add(3);
System.out.println(map.get(lis)); // Prints "null", *not* "7"
它第二次解析为不同的bucket,因此它将其视为第二个元素
在这种情况下,您可以使用Collections.unmodifiableList
来“冻结”列表,添加它,然后再也不要触摸它:
map.put(lis, 7);
lis.add(3);
map.put(lis, 7);
System.out.println(map.size()); // Prints "2"
然后,如果稍后调用get()。添加(3)
:
这将抛出一个
不支持操作异常
这是因为lis和lis2的哈希代码相等
lis2.hashCode()==lis.hashCode()为true
源代码(HashMap)中的方法包含skey,如下所示:
map.get(7).add(3);
/**
*如果此映射包含
*指定的密钥。
*
*@param key此映射中存在的密钥将被测试
*@如果此映射包含指定对象的映射,则返回true
*钥匙。
*/
公共布尔containsKey(对象键){
对象k=maskNull(键);
int hash=hash(k.hashCode());
int i=indexFor(散列,table.length);
条目e=表[i];
while(e!=null){
if(e.hash==hash&&eq(k,e.key))
返回true;
e=e.next;
}
返回false;
}
您将哈希映射定义为
/**
* Returns <tt>true</tt> if this map contains a mapping for the
* specified key.
*
* @param key The key whose presence in this map is to be tested
* @return <tt>true</tt> if this map contains a mapping for the specified
* key.
*/
public boolean containsKey(Object key) {
Object k = maskNull(key);
int hash = hash(k.hashCode());
int i = indexFor(hash, table.length);
Entry e = table[i];
while (e != null) {
if (e.hash == hash && eq(k, e.key))
return true;
e = e.next;
}
return false;
}
HashMap map=newhashmap();
因此,键是一个整数列表,值是一个整数
map.containsKey(lis2)将尝试为给定的键查找匹配项。因此,将在每个键上调用equals方法。由于键实际上是一个整数列表,因此将按顺序对该列表的每个项调用equal方法
这就是为什么输出是正确的
如果更改第二个列表中的任何项目,甚至更改项目的顺序,则输出将为false。
map.containsKey
如果此映射包含指定键的映射,则返回true
。它使用键的equals
方法检查是否相等:
HashMap<ArrayList<Integer>, Integer> map = new HashMap<ArrayList<Integer>, Integer>();
如果(从ArrayList doc复制)出现以下情况,则称两个ArrayList相等:
比较指定对象与此列表是否相等。退换商品
当且仅当指定对象也是列表时为true,两个列表
具有相同的大小,且所有对应的两个元素对
名单是平等的。(如果(e1==null,则两个元素e1和e2相等。)?
e2==null:e1.equals(e2)))换句话说,两个列表被定义为
如果它们包含相同顺序的相同元素,则表示相等
此实现首先检查指定的对象是否在此列表中。
如果是,则返回true;如果不是,则检查指定的对象是否为
列表如果不是,则返回false;如果是这样,它将在两个列表上迭代,
比较对应的元素对。如果有比较返回
false,此方法返回false。如果任一迭代器的
元素之前的其他元素返回false(如列表所示)
长度不等);否则,在迭代时返回true
完成
由于这两个列表包含相同顺序的相同数量的元素,因此它们被认为是相等的
,这就是map.containsKey(lis2)
返回true
的原因。它首先检查hashCode(),以便知道在哪里查找要调用相等的对象。我对此表示异议。请看下面的答案MouseLearnJava@Peter修正了,也增加了关于可变键的更新(biiiig no no),它还检查eq(k,e.key)
调用中的equals
。
/**
* Returns <tt>true</tt> if this map contains a mapping for the
* specified key.
*
* @param key The key whose presence in this map is to be tested
* @return <tt>true</tt> if this map contains a mapping for the specified
* key.
*/
public boolean containsKey(Object key) {
Object k = maskNull(key);
int hash = hash(k.hashCode());
int i = indexFor(hash, table.length);
Entry e = table[i];
while (e != null) {
if (e.hash == hash && eq(k, e.key))
return true;
e = e.next;
}
return false;
}
HashMap<ArrayList<Integer>, Integer> map = new HashMap<ArrayList<Integer>, Integer>();
key != null && key.equals(k)