Java集合有大主干————Collection和Map
1. Collection接口
- List接口【有序,可重复】
- LinkedList类-->双向链表
- ArrayList类--->数组
- Vector类(跟ArrayList功能类似,但是更慢,少用)--->数组
- Stack类--->继承Vector类
- Set接口【唯一】
- HashSet类【无序,唯一】==>底层数据结构是哈希表==》通用的存储数据的集合--->依赖HashMap实现
- LinkedHashSet类【插入有序,唯一】==》底层数据结构是链表(保证有序)和哈希表(保证唯一)==》保证有序的集合(先进先出)--->继承HashSet类
- TreeSet类【有序,唯一】==>底层数据结构是红黑树==》用于排序--->依赖TreeMap实现
- Queue接口
- LinkedList类==》先进先出
2. Map接口【无重复的Key】
- HashTable类【无序】
- HashMap类【无序】
- HashMap中元素的遍历是按照从数组起始位置开始,首先将当前bucket下的所有元素遍历完成,然后到下一个bucket,bucket与bucket之间如果为空就跳到下一个bucket,直到将所有的元素遍历出来.显而易见,元素插入的位置并不是这样的顺序,因此才说HashMap是无序的.
- LinkedHashMap类【插入有序】
- LinkedHashMap继承HashMap,但是额外维护了一个双向链表,记录插入的顺序,元素遍历的顺序就是链表从前到后的顺序,因此也是有序的.
- TreeMap类【有序】
- TreeMap的底层数据结构是一棵红黑树,红黑树上的元素都是有顺序的.
- HashMap和HashSet的对比
- 两者检索速度的差异主要原因是——HashMap计算key的哈希码(key一般只是数字或字符串),比HashSet计算整个对象的哈希码要快得多
- HashSet底层用HashMap容器
-
TreeMap和TreeSet对比
- TreeSet底层使用TreeMap容器
-
大一统整理
- 注意:JDK1.8之前,哈希表底层使用数组+链表存储实现,用链表处理冲突,同一个hash值的链表都存储在一个链表里,但是当一个桶中的元素较多,通过key依次检索链表的效率低,所以1.8中,哈希表采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,链表转换为红黑树,提升效率
- 哈希表的数组+链表结构
- 哈希表的数组+链表+红黑树结构
-
集合的对比
-
数组与集合的对比
- 既可以创建为保存基本数据类型的值也可以保存对象的引用;集合只能保存对象的引用,可以使用包装类(Integer、Double等)保存基本数据类型的值
-
其他细节
- list.add(list1)和list.add(new ArrayList<>(list1))的区别在于:
//第一种情况: List<List<Integer>> res = new ArrayList<>(); List<Integer> row = new ArrayList<>(); for (int i = 1; i <= 3; i++) { row.add(i); res.add(row); } //结果: //row:[1,2,3] //res: [[1,2,3],[1,2,3],[1,2,3]] //只创建了两个对象,res和row,最后添加进res的是三个同样的对象row的引用。 //第二种情况: for (int i = 1; i <= 3; i++) { row.add(i); res.add(new ArrayList<>(row)); } //结果: //row:[1,2,3] //res: [[1],[1,2],[1,2,3]] //创建了5个对象,res,row以及row的三个不同时刻的拷贝。