目录
1.Set系列集合
- 无序:存取顺序不一致
- 不重复:可以去除重复
- 无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素
Set集合的方法上基本上与Collection的API一致
Set集合的实现类:
- Hashset:无序、不重复、无索引
- LinkedHashset:有序、不重复、无索引
- Treeset:可排序、不重复、无索引
2.HashSet
顶层实现是哈希表的Set
加载因子代表HashSet的扩容时机,当数组里面存了16×0.75=12个元素时,数组就会从16扩容成32,并且当链表长度大于8而且数组长度大于等于64,当前链表就会自动转变成红黑树,从而提高查找效率,如果集合中存储的是自定义对象,必须要重写hashCode和equals方法,因为不重写的话默认都是用地址值比较的,意义不大。
问题1:Hashset为什么存和取的顺序不一样?
HashSet遍历的规则是按照数组的索引遍历每一个位置的链表,所以和加入HastSet的顺序肯定是不一样的。
问题2:Hashset为什么没有索引?
因为HashSet底层是数组、链表、红黑树组合而成的,不好规定索引。
问题3:Hashset是利用什么机制保证数据去重的?
HashSet利用HashCode()和equals()方法保证去重,HashCode()获取元素哈希值从而确定存放位置,equals()比较元素内部属性值,从而保证不重复。
3.LinkedHashSet
底层基于哈希表,使用双链表记录添加顺序
LinkedHashSet遍历时就是双向链表,所以可以保证有序。
在以后如果要数据去重,我们使用哪个?
默认使用HashSet,如果要求去重且存取有序,才使用LinkedHashSet。
4.TreeSet
- 不重复、无索引、可排序(与有序不同)
- 可排序:按照元素的默认规则(有小到大)排序
- TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好
Treeset的两种比较方式:
- 默认排序/自然排序:Javabean类实现Comparable接口指定比较规则
- 比较器排序:创建Treeset对象时候,传递比较器Comparator指定规则
使用原则:默认使用第一种,如果第一种不能满足当前需求,就使用第二种
1.TreeSet默认的排序规则:
- 对于数值类型:Integer,Double,默认按照从小到大的顺序进行排序
- 对于字符、字符串类型:按照字符在ASCII码表中的数字升序进行排序
//强制类型转换,将char字符转为int类型 char c = 'a'; int intc = (int)c; System.out.println("a的ASCII值是:"+intc);//仍打印的是a的ASCII值
TreeSet需要指定排序规则,compareTo方法,不需要重写hashcode和equals,因为TreeSet排序与哈希表无关,底层是红黑树。
2.TreeSet比较器排序
//Treeset<String> ts = new Treeset<>(new Comparator());
Treeset<String> ts = new Treeset<>((o1,o2)->{
// 按照长度排序
int i = o1.length() - o2.length();
//如果一样长则按照首字母排序
i = i == 0 ? o1.compareTo(o2) : i;
return i;
});
总结:
1.Treeset集合的特点是怎么样的?
- 可排序、不重复、无索引
- 底层基于红黑树实现排序,增删改查性能较好
2.Treeset集合自定义排序规则有几种方式?
- 方式一:Javabean类实现Comparable接口,指定比较规则
- 方式二:创建集合时,自定义Comparator比较器对象,指定比较规则
3.方法返回值的特点是什么?
- 负数:表示当前要添加的元素是小的,存左边
- 正数:表示当前要添加的元素是大的,存右边
- 0:表示当前要添加的元素已经存在,舍弃
4.那么目前为止学了这么多单列集合,它们的使用场景?
- 如果想要集合中的元素可重复,用ArrayList集合,基于数组的(用的最多)
- 如果想对集合中的元素去重,用HashSet集合,基于哈希表的(用的最多)