use*_*433 6 java hashtable hashmap containskey
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));
Run Code Online (Sandbox Code Playgroud)
最初,我希望代码打印出'false',因为lis和lis2是不同的对象.令人惊讶的是,代码打印出"真实".hashmap在调用containsKey()时检查什么?
它检查.hashCode以找到存储桶,然后使用.equals.List.equals返回true如果所有元素都以相同的顺序和也是.equals.ArrayList.hashCode将为ArrayList具有相同元素的两个实例返回相同的值,因此它会找到正确的存储桶,然后使用.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);
System.out.println(lis.equals(lis2)); // Prints "true"
Run Code Online (Sandbox Code Playgroud)
值得注意的是,你永远不应该使用一个可变对象作为你的关键HashMap.通过修改密钥,可以使其所在的存储桶无效.例如,如果我这样做:
map.put(lis, 7);
lis.add(3);
System.out.println(map.get(lis)); // Prints "null", *not* "7"
Run Code Online (Sandbox Code Playgroud)
这是因为添加另一个元素会改变其值lis.hashCode().当你put的单,hashCode是用来挑水桶.通过添加新元素,您可以更改它将使用的存储桶,但不会更改已添加到地图的条目的存储桶.添加到上面:
map.put(lis, 7);
lis.add(3);
map.put(lis, 7);
System.out.println(map.size()); // Prints "2"
Run Code Online (Sandbox Code Playgroud)
它第二次解析为另一个桶,因此它将其视为第二个元素.
在这种情况下,您将使用Collections.unmodifiableList"冻结"列表,添加它,然后再从未触摸它:
map.put(Collections.unmodifiableList(lis), 7);
Run Code Online (Sandbox Code Playgroud)
然后,如果你打电话get().add(3):
map.get(7).add(3);
Run Code Online (Sandbox Code Playgroud)
这将抛出一个UnsupportedOperationException.
| 归档时间: |
|
| 查看次数: |
3377 次 |
| 最近记录: |