0
点赞
收藏
分享

微信扫一扫

java中Set集合接口的常见问题解析

1,set结合如何实现及如何实现过滤重复元素: 它的三个实现类:

HashSet

存进去的元素顺序是无序的,根据它的hash码来决定它的位置,都是去调用了HashMap的构造方法,利用它的key唯一去实现值唯一,

LinkedHashSet由于链表的原因相对于Hashset是有顺序的,去调用了LinkedHashMap的构造方法

Treeset由于调用了TreeMap的构造方法,所以会去给元素排序的

过滤重复元素:

1,先是把每个元素的hash码用来你比较,如果hash码不一样,则直接返回false,及判断元素不一样,如果hash码一样,并不能直接判断元素使一样的,由于hash码他也是有范围的及就是int 范围不同元素的hash码有可能是一样的。所以会进行第二步

2,用equals()方法比较元素的值是否相同,结果是唯一的。

之所以会用两个方式去比较,由于用hash码比较效率比较高,而equals方法比较效率比较低。

2,为何hashCode()和equals()方法在重写时要去同时重写 具体体现在set集合和map集合去重复元素这里,hashCode()对于引用类型的数据没重写之前它是根据地址去计算hash码的,equals()没重写之前去比较地址是否一样,两者都是通过地址去比较一个引用类型的对象是否一致,而当你只取重写其中一个方法时,在set集合这里去重复元素时,就不会达到预期的结果,假如当你只去重写hashcode方法是且去比较两个地址不同但元素内一样时,当判断元素的hash码一样时,你要进行第二步的元素比较equals方法,此时你没有重写,它是去根据地址比较,他比较的结果是地址不同但元素内容一样的元素是不同的两个元素,在set结合这里达不想要的结果。因此两个方法必须同时重写用相同的比较方式去比较元素是否一致才会去达到预期结果。

3,hash码冲突的原因 在计算hash码时是根据地址去计算,返回一int类型的十六进制的整数,要知道int他还是有范围的,当数据产生溢出时它会在原来的十六进制上减去int数据类型的模,以保证他在int类型的范围。这样就会产生一个循环,当两个数据的十六进制数的差刚好是int的正数范围,那么他们的hash码必然一样。但是实际数据并不一样。

举报

相关推荐

0 条评论