62,628
社区成员
发帖
与我相关
我的任务
分享HashSet的内部还是用HashMap来实现的,原理都差不多。
你这个程序的输出是这样执行的:
1、hs.add(x);的时候,它会计算hash值,会调用hashCode这个函数(输出了hashCode执行了),因为你这里重写了,所以hash值总为1,然后判断当前的hash表中有无和这个hash值一样的,这里因为是第一个,所以没有,添加进入hash表;
2、hs.add(x);的时候,一样计算hash值(输出hashCode执行了),过程和上面一样,hash值为1,然后判断当前hash表中有一个和这个hash值一样的,接下来继续判断,x和hash表中这个元素(hash值为1那个)是否相等(对象相等==),这里相等,所以直接返回,不添加。
3、hs.add(y);,和2流程基本一致,先判断hash值(输出了hashCode执行了),有相等,继续判断对象是否相等,发现不等,接下来就是你疑惑的重点了,它还会进行equals()方法(输出equals执行了),因为你重写了,总是返回false,所以这里判断不通过,添加。
下面就是关键地方的判断源代码:
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
e.hash:hash表中的那个hash值
hash:添加那个对象的hash值
key:添加的对象,这里就是x和y
k = e.key:表中那个对象
关键在于 && 后面的那个表达式,如果 || 前面的(k = e.key) == key为true的后,java中是不会计算后面的那个的,就直接返回true了,因为不管后面的是true还是false,都不影响结果;反过来,如果前面的为false,才会计算后面那个。
这个就是你第二次添加x的时候,没有调用equals方法的原因所在!
说的比较啰嗦,但愿你能看懂~~~