-
Java集合之Set
Set接口
1 Set接口概述
- Set接口是Collection的子接口,set接口没有提供额外的方法
- Set集合是一个无序不可重复的集合,如果试把两个相同的元素加入同一个Set集合中,则添加操作失败。
- Set判断两个对象是否相同不是使用==运算符,而是根据equals()方法
- 没有索引,不能使用普通的for循环遍历
2 Set的实现类之一:HashSet
2.1 HashSet的概述
- HashSet是Set 接口的典型实现,大多数时候使用Set集合时都使用这个实现类。
- HashSet按Hash算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。
- HashSet 具有以下特点:
- 不能保证元素的排列顺序
- HashSet不是线程安全的
- 集合元素可以是null
- HashSet集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。
- 对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode()方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。
2.2 HashSet添加元素的过程(重点)
当向HashSet集合中存入一个元素时:
- HashSet会调用该对象的**hashCode()**方法来得到该对象的hashCode值,然后根据hashCode值,通过某种散列函数决定该对象在HashSet底层数组中的存储位置
- 如果两个元素的hashCode()值相等,会再继续调用**equals()**方法
- 如果返回值为true,添加失败
- 如果返回值为false,那么会保存该元素。但是该数组的位置已经有元素了,那么会通过链表的方式继续链接
- 如果两个元素的equals()方法返回true,但它们的hashCode()返回值不相等,hashSet将会把它们存储在不同的位置,但依然可以添加成功。
2.3 重写hashCode()方法的基本原则
- 在程序运行时,同一个对象多次调用hashCode()方法应该返回相同的值。
- 当两个对象的equals()方法比较返回 true 时,这两个对象的hashCode()方法的返回值也应相等。
- 对象中用作equals()方法比较的Field,都应该用来计算hashCode值。
2.4 重写equals()方法的基本原则
- 相等的对象必须具有相等的散列码
- 复写equals方法的时候一般都需要同时复写hashCode方法。通常参与计算hashCode的对象的属性也应该参与到equals()中进行计算。
2.5 拓展知识
3 Set的实现类之二:LinkedHashSet
- LinkedHashSet的特点:
- LinkedHashSet是HashSet的子类
- LinkedHashSet根据元素的hashCode值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
- LinkedHashSet插入性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。
- LinkedHashSet不允许集合元素重复
4 Set的实现类之三:TreeSet
4.1 TreeSet概述
- TreeSet是SortedSet接口的实现类,TreeSet 可以确保集合元素处于排序状态。
- TreeSet底层使用红黑树结构存储数据
- TreeSet两种排序方法:自然排序和定制排序。默认情况下,TreeSet采用自然排序
4.2 自然排序
- TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列
- 如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。
- 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过
compareTo(Object obj) 方法的返回值来比较大小
- Comparable 的典型实现:
- BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较
- Character:按字符的 unicode值来进行比较
- Boolean:true 对应的包装类实例大于 false 对应的包装类实例
- String:按字符串中字符的 unicode 值进行比较
- Date、Time:后边的时间、日期比前面的时间、日期大
- 向TreeSet中添加元素时,只有第一个元素无须比较compareTo()方法,后面添加的所有元素都会调用compareTo()方法进行比较。
- 因为只有相同类的两个实例才会比较大小,所以向TreeSet中添加的应该是同一个类的对象
- 对于TreeSet集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过 compareTo() 方法比较返回值
- 当需要把一个对象放入TreeSet中,重写该对象对应的 equals() 方法时,应保证该方法与 compareTo( ) 方法有一致的结果:如果两个对象通过equals() 方法比较返回 true,则通过 compareTo()方法比较应返回 0.
4.3 定制排序
- TreeSet的自然排序要求元素所属的类实现Comparable接口,如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要**重写compare()**方法。
- 利用int compare(T o1,T o2)方法,比较o1和o2的大小:
- 如果方法返回正整数,则表示o1大于o2;
- 如果返回0,表示相等;
- 返回负整数,表示o1小于o2。
- 要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。此时,仍然只能向TreeSet中添加类型相同的对象。否则发生ClassCastException异常。
- 使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0
-
相关阅读:
物种基因组大小查询之流式结果查询
Java Spring Redis实现过期键监听回调
rsync+inotify-tools文件传输
OpenCV图像处理——傅里叶变换
PCM会重塑汽车OTA格局吗(2)
技术分享 | web自动化测试-文件上传与弹框处理
Baklib|搭建帮助中心,推动SaaS企业发展
【Redis入门笔记 02】基础知识与常见数据类型
LeetCode 每日一题 2022/11/14-2022/11/20
【文献阅读】【NC 2023】基于分子组装的可解释深度学习方法实现精准逆合成预测以及路径规划
-
原文地址:https://blog.csdn.net/qq_52248567/article/details/126512308