1.Java集合类使用总结
1.1概览
Java 集合, 也叫作容器,主要是由两大接口派生而来:一个是 Collection
接口,主要用于存放单一元素;另一个是 Map
接口,主要用于存放键值对。对于Collection
接口,下面又有两个个主要的子接口:List
、Set
1.1.1集合接口类特性
- Collection接口:存储无序,不唯一的对象
- List接口:存储有序,不唯一的对象
- Set接口:存储无序,唯一的对象
- Map接口:存储 键值(key-value) 对象
1.1.2List接口和Set接口的区别
- 存储元素不同:
- List接口存储不唯一,有序的对象
- Set接口存储唯一,不唯一的对象
- 查找/删除和插入效率不同:
- Set 查找效率低,删除和插入效率高,插入和删除不会引起元素位置改变。
- List查找元素效率高,插入删除效率低,因为会引起其他元素位置改变
1.1.3简要介绍
(1)List接口
ArrayList
:Object[]
数组。。LinkedList
:双向链表(JDK1.6 之前为循环链表,JDK1.7 取消了循环)
(2)Set接口
-
HashSet
(无序,唯一): 基于HashMap
实现的,底层采用HashMap
来保存元素。 -
LinkedHashSet
:LinkedHashSet
是HashSet
的子类,并且其内部是通过LinkedHashMap
来实现的。 -
TreeSet
(有序,唯一): 红黑树(自平衡的排序二叉树)
(3)Map接口
HashMap
:JDK1.8 之前HashMap
由数组+链表组成的,数组是HashMap
的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。- LinkedHashMap
:
LinkedHashMap继承自
HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,
LinkedHashMap在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。详细可以查看:[LinkedHashMap 源码分析]()
- Hashtable
:数组+链表组成的,数组是
Hashtable的主体,链表则是主要为了解决哈希冲突而存在的。
- TreeMap`:红黑树(自平衡的排序二叉树)
1.2Collection接口
Collection 接口是层次结构中的根接口。构成 Collection 的单位称为元素。Collection 接口通常不能直接使用,但该接口提供了添加元素、删除元素、管理数据的方法。由于 List 接口与 Set 接口都继承了 Collection 接口,因此这些方法对 List 集合与 Set 集合是通用的。
- 常用方法:
方法 | 描述 |
---|---|
add(E e) | 将指定的对象添加到该集合中 |
remove(Object o) | 将指定的对象从该集合中移除 |
isEmpty() | 返回 boolean 值,用于判断当前集合是否为空 |
iterator() | 返回在此 Collection 的元素上进行迭代的迭代器。用于遍历集合中的对象 |
size() | 返回 int 型值,获取该集合中元素的个数 |
- 遍历集合
1.3List接口
1.3.1ArrayList
- 存储对象:
ArrayList
中只能存储引用类型数据的对象。对于基本类型数据,需要使用其对应的包装类 - 底层数据结构:底层使用
Object[]
存储,适用于频繁的查找工作,线程不安全 - null值问题:可以添加null值
- 线程安全问题:不安全
- 数组大小:
ArrayList
创建时不需要指定大小,会根据实际存储的元素动态地扩容或缩容,ArrayList
允许使用泛型来确保类型安全
1.3.2LinkedList—不常用
- 存储对象:存储对象:LinkedList 可以存储任意类型的对象,包括基本数据类型和引用数据类型
- 底层数据结构:LinkedList 的底层数据结构是双向链表,通过一个 Node 内部类实现的这种链表结构
- null值问题:LinkedList 允许存储 null 值作为元素
- 线程安全问题:不安全
1.3.3区分ArrayList与LinkedList
ArrayList | LinkedList | |
---|---|---|
线程安全 | 不安全 | 不安全 |
底层数据结构 | Object数组 | 双向链表(JDK1.6 之前为循环链表,JDK1.7 取消了循环。注意双向链表和双向循环链表的区别) |
插入和删除是否受元素位置的影响 | 采用数组存储,受影响(O(1)或者O(n)) | 链表存储,指定位置插入删除、首尾(O(1))、O(n) |
是否支持快速随机访问 | 实现了 RandomAccess 接口,通过元素的序号快速获取元素对象(对应于get(int index) 方法) |
不支持 |
内存空间占用 | 空间浪费主要体现在在 list 列表的结尾会预留一定的容量空间 | LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(前驱和后驱) |
1.4Set接口
Set 接口常用的实现类有 HashSet 、LinkedHashSet、TreeSet。
1.4.1HashSet
- 存储对象:HashSet 存储对象采用哈希表的方式,它不允许重复元素,即集合中不会包含相同的元素。当向 HashSet 中添加元素时,会根据元素的 hashCode() 方法和 equals() 方法来判断元素是否重复。
- 底层数据结构:HashSet 的底层数据结构是基于 HashMap 实现的,实际上 HashSet 的元素就是作为 HashMap 的 key 存储的。
- null 值问题:HashSet 允许存储一个 null 元素。
- 线程安全问题:不安全