本篇文章讲解的知识点主要围绕集合-set接口,废话不多说,只分享Java相关的干货!
哈希表
哈希表是一种数据结构,哈希表能够提供快速存取操作。哈希表是基于数组的,所以也存在缺点,数组一旦创建将不能扩展。
正常的数组,如果需要查询某个值,需要对数组进行遍历,只是一种线性查找,查找的速度比较慢。如果数组中的元素值和下标能够存在明确的对应关系,那么通过数组元素的值就可以换算出数据元素的下标,通过下标就可以快数定位数组元素,这样的数组就是哈希表。一张哈希表:
元素值 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
元素下标 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
以上我们的示例元素值和下标的关系为:
元素下标=元素值-10,此时的示例hashcode 就是和数组下标一致了,取得hashcode 方法如下:
有了hashCode 后,我们就可以快速的定位相应的元素,查找到相应的信
HashSet
HashSet 中的数据是无序的不可重复的。HashSet 按照哈希算法存取数据的,具有非常好性能, 它的工作原理是这样的,当向 HashSet 中插入数据的时候,他会调用对象的 hashCode 得到该对象的哈希码,然后根据哈希码计算出该对象插入到集合中的位置。
equals 和 hashCode
加入了重复的数据,因为hashCode 是不同的,所以会根据算出不同的位置,存储格式
Person{张三,20} |
Person{李四,30} |
Person{张三,40} |
7699183 |
14285251 |
10267414 |
进一步完善,覆盖equals
以上仍然存在重复数据,在 Person 中覆盖了hashCode 方法,能够正确的比较出两个Person 是相等的还是不等的,但是为什么 HashSet 中还是放入了重复数据?因为Person 对象的hashCode 不同,所以它就换算出了不同的位置,让后就会把相关的值放到不同的位置上,就忽略equlas, 所以我们必须覆盖hashCode 方法
Person{张三,20} |
Person{李四,30} |
Person{张三,40} |
7699183 |
14285251 |
10267414 |
【代码示例】,只覆盖hashCode,不覆盖equals
以上示例,张三的 hashCode 相同,当两个对象的equals 不同,所以认为值是以不一样的,那么java 会随机换算出一个新的位置,放重复数据
Person{张三,20} |
Person{李四,30} |
Person{张三,40} |
774889-1 |
14285251 |
774889-2 |
【代码示例】,进一步改善,覆盖equals,覆盖hashCode
以上输出完全正确的,因为覆盖了equals 和hashCode,当 hashCode 相同,它会调用equals 进行比较,如果equals 比较相等将不加把此元素加入到Set 中,但 equals 比较不相等会重新根据hashCode 换算位置仍然会将该元素加入进去的。
Person{张三,20} |
Person{李四,30} |
|
774889 |
842061 |
|
再次强调:特别是向 HashSet 或HashMap 中加入数据时必须同时覆盖equals 和 hashCode 方法,应该养成一种习惯覆盖equals 的同时最好同时覆盖hashCode
Java 要求:
- 两个对象equals 相等,那么它的hashcode 相等
- 两个对象equals 不相等,那么它的hashcode 并不要求它不相等,但一般建议不相等
- hashcode 相等不代表两个对象相等(采用equals 比较)
TreeSet
TreeSet 可以对Set 集合进行排序,默认自然排序(即升序),但也可以做客户化的排序
以上没有输出重复的,是按自然顺序排序的(升序)
【代码示例】,对Person 进行自然排序
出现错误,因为放到 TreeSet 中 TreeSet 会对其进行排序,那么必须实现Comparable 接口,而我们的 Person 没有实现,所以出现了错误,如:基本类型的包装类和 String 他们都是可以排序的,他们都实现Comparable 接口
实现 Comparable 接口完成排序
实现 Comparator 接口完成排序
采用匿名类完成 Comparator 的实现
Comparable 和 Comparator 的区别?
一个类实现了 Camparable 接口则表明这个类的对象之间是可以相互比较的,这个类对象组成 的集合就可以直接使用sort 方法排序。
Comparator 可以看成一种算法的实现,将算法和数据分离,Comparator 也可以在下面两种环境下使用:
1、类的没有考虑到比较问题而没有实现 Comparable,可以通过 Comparator 来实现排序而不必改变对象本身
2、可以使用多种排序标准,比如升序、降序等
以上就是集合Set接口知识点,配套视频教程👇,正在学习Java的同学们一定要持续关注哦~~
Java零基础进阶视频教程
转载:https://blog.csdn.net/bjpowernode_com/article/details/113626422