HashMap<List<Integer>, String> key问题
size 为1?
@Test
public void testEmptyListKey() {
HashMap<List<Integer>, String> listStringHashMap = new HashMap<List<Integer>, String>() {
{
put(new ArrayList<Integer>(), "bb");
put(new ArrayList<Integer>(), "cc");
}
};
// size 为1
System.out.println(listStringHashMap.size());
}
put 方法
如何判断key是否存在?
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
// 在这里,遍历 map里的key,与传入的key比较
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
=======重点======
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
首先 hash一定要相等,然后==相等或者equals相等
所以问题变成:new 多个 ArrayList<Integer>(),但里面的数字相等,ArrayList equals 也相等?至少对放Integer的时候是相等的
ArrayList 的 equals
/**
* ArrayList 的equals
*/
@Test
public void testList() {
List<Integer> integerList = new ArrayList<>();
List<Integer> integerList1 = new ArrayList<>();
// 结果为true
System.out.println(integerList.equals(integerList1));
// 加了一个数
integerList.add(3);
// 结果为false
System.out.println(integerList.equals(integerList1));
integerList1.add(3);
// true
System.out.println(integerList.equals(integerList1));
}
ArrayLsit 的equals 继承自 AbstractList
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator<?> e2 = ((List<?>) o).listIterator();
while (e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
可以看出,当list 里面的东西 按顺序比较equals 相等时,就认为是一个相等的
注意: 顺序要一样噢
/**
* 元素顺序一样才能equals 为 true
*/
@Test
public void testTwo() {
List<Integer> integerListOne = new ArrayList<Integer>() {
{
add(1234);
add(3455);
}
};
List<Integer> integerListTwo = new ArrayList<Integer>() {
{
add(3455);
add(1234);
}
};
List<Integer> integerListThree = new ArrayList<Integer>() {
{
add(3455);
add(1234);
}
};
// 结果为false
System.out.println(integerListOne.equals(integerListTwo));
// true
System.out.println(integerListTwo.equals(integerListThree));
}
总结
HashMap 判断key是否存在:equals 相等。而List的equals 是遍历里面的元素,依次是否相等。