Set接口:存储无有序、不可重复数据。(无序且唯一,使用equals
进行比较)
- 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的。
不可重复性:保证添加的元素按照equals()判断时,不能返回true.即:相同的元素只能添加一个。
|----HashSet:作为Set接口的主要实现类;线程不安全的;可以存储null值 |----LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历 对于频繁的遍历操作,LinkedHashSet效率高于HashSet. |---TreeSet
HashSet
特点:
- 底层也是数组,初始容量为16,当如果使用率超过0.75,(16*0.75=12)
就会扩大容量为原来的2倍。(16扩容为32,依次为64,128....等) - 不能保证元素的排列顺序
- HashSet 不是线程安全的
- 集合元素可以是 null
- 底层也是数组,初始容量为16,当如果使用率超过0.75,(16*0.75=12)
注意点:
- HashSet必须要重写equals方法和hashcode()方法
- 向HashSet中添加元素的过程
我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,
此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置)数组此位置上是否已经有元素: - 如果此位置上没有其他元素,则元素a添加成功。 --->情况1
如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
- 如果hash值不相同,则元素a添加成功。--->情况2
如果hash值相同,进而需要调用元素a所在类的equals()方法:
- equals()返回true,元素a添加失败
- equals()返回false,则元素a添加成功。--->情况3
HashSet底层:数组+链表的结构。
---
向TreeSet中添加的数据,要求是相同类的对象。
- 两种排序方式:自然排序(实现Comparable接口) 和 定制排序(Comparator)
1. 自然排序中,比较两个对象是否相同的标准为:compareTo()返回0.不再是equals().
2. 定制排序中,比较两个对象是否相同的标准为:compare()返回0.不再是equals().
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person && o2 instanceof Person){
Person p1= (Person) o1;
Person p2= (Person) o2;
return -p1.getName().compareTo(p2.getName());
}
throw new RuntimeException("类型不一致!");
}