记录一下自己在蓝桥云课里的学习过程,每天进步一点点
目录
一、Set集合
二、Set主要方法:
三、HashSet
1.HashSet 是如何判断元素重复的?
2.为什么要重写equals()和hashCode()
四、TreeSet
五、比较器
1.内部比较器Comparable 接口
2.外部比较器Comparator 接口
Set 是 Collection 的子接口。Set 中的元素是不能重复的、无序的,这里的“无序”是指向 Set 中输入的元素,与从 Set 中输出元素的顺序是不一致的。
boolean add(Object obj)
向集合中添加一个 obj 元素,并且 obj 不能和集合中现有数据元素重复,添加成功后返回 true。如果添加的是重复元素,则添加操作无效,并返回 false。
void clear()
移除此集合中的所有数据元素,即将集合清空。
boolean contains(Object obj)
判断此集合中是否包含 obj,如果包含,则返回 true。
boolean isEmpty()
判断集合是否为空,为空则返回 true。
Iterator iterator()
返回一个 Iterator 对象,可用它来遍历集合中的数据元素。
boolean remove(Object obj)
如果此集合中包含 obj,则将其删除,并返回 true。
int size()
返回集合中真实存放数据元素的个数,注意与数组、字符串获取长度的方法的区别。
Object[] toArray()
返回一个数组,该数组包含集合中的所有数据元素。
Set 接口主要有两个实现类 HashSet 和 TreeSet
如果逐个比较 HashSet 中的全部元素,显然是一种效率低下的做法。因此 HashSet 的底层引入了 hashcode。如果两个对象相等,那么这两个对象的 hashcode 值相同,但反之,如果两个对象的 hashcode 值相同,则这两个对象可能相等,也可能不等,需要再通过 equals()
进一步比较这两个对象的内容是否相同。
向 HashSet 中增加元素时,HashSet 会先计算此元素的 hashcode,如果 hashcode 值与 HashSet 集合中的其他元素的 hashcode 都不相同,那么就能断定此元素是唯一的。否则,如果 hashcode 值与 HashSet 集合中的某个元素的 hashcode 相同,HashSet 就会继续调用 euqals()
方法进一步判断它们的内容是否相同,如果相同就忽略这个新增的元素,如果不同就把它增加到 HashSet 中。因此,在实际开发中,当使用 HashSet 存放某个自定义对象时,就得先在这个对象的定义类中重写 hashcode()
和 equals()
方法。
equals()
和hashCode()
比如说我们要使用 equals()方法判断对象是否相同,其一是
比较的是对象的内存地址是否相同,其二是如果对象的所有属性都一样则我们也认为这两个对象是相同的,故需要用对象的所有属性来计算hashCode,但是Object 中定义的 equals()
方法默认比较的是对象的内存地址;hashCode()
方法的前面有 native
修饰符,表示会通过操作系统底层提供的算法来计算 hash 值显然,这两个方法的默认实现,与我们“关注对象内容”的侧重点不一致,因此需要重写。
TreeSet 类在实现了 Set 接口的同时,也实现了 SortedSet 接口,是一个具有排序功能的 Set 接口类,TreeSet 集合中的元素默认是按照自然升序排列,并且 TreeSet 集合中的对象需要实现 Comparable 接口。Comparable 接口用于比较集合中各个元素的大小,常用于排序操作。
JDK 提供了 Comparable
和 Comparator
两个接口,都可以用于定于集合元素的排序规则
如果程序员想定义自己的排序方式,一种简单的方法就是让加入 TreeSet 集合中的对象所属的类实现 Comparable 接口,通过实现 compareTo(Object o)
方法,达到排序的目的。
Comparator 可以理解为一个专用的比较器,当集合中的对象不支持自比较或者自比较的功能不能满足程序员的需求时,就可以写一个实现 Comparator 接口的比较器来完成两个对象之间的比较,从而实现按比较器规则进行排序的功能。例如要比较的对象是 JDK 中内置的某个类,而这个类又没有实现 Comparable 接口,因此我们是无法直接修改 JDK 内置类的源码的,因此就不能通过重写 compareTo(Object o)
方法来定义排序规则了,而应该使用 Comparator 接口实现比较器功能