java集合框架里面有list set map。
list可以按照下标存取元素。
set可以保证唯一性。
map按照键值存取。键必须唯一,值可以相同。
今天要说的是和hash算法有关的集合 HashSet
HashSet可以保存元素唯一。如果HashSet里面存放的是自定义的类型,怎么保证HashSet知道怎么区分唯一呢?
原来在java中判断两个对象是否相同时通过hashCode 和 equals()来实现的。
hashCode()默认的行为会返回每个对象特有的序号(大部分的java版本是依据内存位置计算此序号,所有不会有相同的hashCode)。
那是不是说hashCode相同的两个引用,他们就一定是相等呢??
答案是否定的,因为hashCode()所使用的hash算法有一定的几率也许刚好会让多个对象传回相同的哈希值。采用的hash算法越槽糕越容易产生碰撞。那这个时候怎么办呢??
java中元素相等判断规定(hashCode()和equals()的规定):
1、如果两个对象相等,则hashCode必须相等。
2、如果两个对象相等,对其中一个对象调用equals()必须返回true,也就是说若 a.equals(b) 则 b.equals(a);
3、如果两个对象有相同的hashCode值,他们也不一定是相等的,但若两个对象相等,则hashCode值一定相等。
4、若equals()被覆盖过,则hashCode()也必须被覆盖。
5、hashCode()的默认行为时对在heap上的对象产生独特的值。如果你没有覆盖hashCode(),则该类的两个对象怎样也不会被认为是相同的。
6、equals()的默认行为时执行== 的比较。也就是说回去测试两个引用是否对上heap上同一个对象。、
如果equals()没有被覆盖过,两个对象永远都不会被视为相同的。因为不同的对象有不同的字节组合(相同的对象的字节组合是相同的)。
拿HashSet来说,如果它发现hashCode对应多个对象,他会使用equals()来判断是否也完全相同。也就是说hashCode是用来缩小寻找范围,但最后还是要用equals()才能认定是否真的找到相同的对象。