hashcode是对象在hash表中对应的位置.
而hash可能会发生hash冲突,所以可能存在不同对象hashcode是相同的.
class Solution {
public static void main(String[] args) {
Integer a = 223;
Integer b = 223;
System.out.println(a == b);
System.out.println(a.hashCode() == b.hashCode());
}
}
上述代码,因为a与b不在Integer常量池的范围[–128,127]之间它俩必然不相等.
但是第二个输出是true.
我一开始很迷惑,后来想到了equals与hashcode 的关系,就明白所有的包装类都重写了Object的hashcode方法,你如果看源码,就会发现
public static int hashCode(int value) {
return value;
}
直接返回了它的值.
这样就保证了equals与hashcode的关系.
但是查看util中的常用的类,发现PriorityQueue并没有重写hashcode.
我们考虑PriorityQueue的底层是通过数组存储的,只是在进出数组的时候,通过算法保证了堆的性质.相当于直接存数组.
下列代码的结果是2
class Solution {
public static void main(String[] args) {
HashMap<PriorityQueue<Integer>, Integer> map = new HashMap<>();
PriorityQueue<Integer> q = new PriorityQueue<>();
q.add(12);
map.put(q, 1);
PriorityQueue<Integer> q1 = new PriorityQueue<>();
q1.add(12);
map.put(q1, 1);
System.out.println(map.size());
}
}
数组是语言特性,没有覆盖Object的equals与hashcode方法.
所以HashMap以数组为key可能会导致代码与逻辑不符.如果确实需要使用数组中的值作为key,可以转化成List作为HashMap的key,因为AbstractList重写了hashcode.
另外自定义的类,最好自己根据逻辑重写hashcode和equals,以防止使用HashMap,HashSet时出错.