一、集合家谱
- 单列集合 Collection:
- List:
- ArrayList
- LinkedList
- Vector
- Set:
- HashSet
- LinkedHashSet
- TreeSet
- HashSet
- List:
- 双列集合 Map:
- HashMap
- LinkedHashMap
- TreeMap
- Hashtable
- HashMap
单列集合
List
ArrayList 底层:
ArrayList 底层是动态数组,数组在内存上开辟一段连续的内存空间,有索引时查找,可以根据寻址公式:目标地址 = 起始地址 + i * 单个元素所占空间,时间复杂度为 O(1),增加和删除最后一个一位,时间复杂度为 O(1),其他部分由于需要移位,时间复杂度为 O(n)ArrayList 扩容机制:
ArrayList 初始容量为0,在第一次 add 时会初始化为 10,当容量小于当前占用容量(size)+1时,会使用 grow 扩容1.5倍,每次扩容时都要拷贝数组
扩容大小设为1.5倍的原因:是为了在减少扩容次数和降低空间浪费之间取得平衡,扩容倍数过小则会导致频繁扩容和大量数组复制,过大会导致内存浪费LinkedList 底层:
LinkedList 底层是双向链表,双向链表具有多个节点,每个节点都有前驱指针指向前一个节点和后继指针指向后一个节点,查找时需要遍历双向链表,会根据实际来选择从头节点或者尾节点开始遍历,时间复杂度为 O(n),插入和删除时,除了头尾节点时间复杂度为 O(1),其他部位由于需要遍历链表,时间复杂度为 O(n)如何保证 ArrayList 和 LinkedList 线程安全:
使用线程安全的 ArrayList 和 LinkedList1
2List<Object> syncArrayList = Collections.synchronizedList(new ArrayList<>());
List<Object> syncLinkedList = Collections.synchronizedList(new LinkedList<>());在方法内部使用,局部变量线程安全
如何实现数组和 List 之间的转换:
- 数组转 List:使用 JDK 中 java.util.Arrays 工具类的 asList 方法
修改数组内容后,List 受影响 - List 转数组:使用 List 的 toArray 方法,无参 toArray 方法返回 Object 数组,传入初始化长度数组对象,返回该数组对象
修改 List 后,数组不受影响
- 数组转 List:使用 JDK 中 java.util.Arrays 工具类的 asList 方法