一、概览
1. 本文目的:
获得图灵奖的Pascal之父——Nicklaus Wirth说过一句经典的名言“程序就是数据结构加算法!”,作为一个Coder,掌握并深刻理解Java中的数据结构还是很有必要的。
2. 结构图:
3. 部分概念:
哈希表结构:动态数组 + 链表/红黑树
二、List
特点:元素添加顺序和排列顺序相同,可存储相同的值(确切讲是a.equals(b)时,二者都可存储)。
1. ArrayList
数据结构:Object类型的动态数组
线程安全:非线程安全
特点:查找快(按角标直接获取),插入和删除慢(需要移动元素),默认容量为10,1.5倍扩容。
2. LinkedList
数据结构:双链表
线程安全:非线程安全
特点:插入和删除快,查找慢(需遍历链表),单个元素占用空间大(因为要储存前驱和后继)。
3. Vector
数据结构:Object类型的动态数组
线程安全:线程安全
特点:与ArrayList一致,但因为其同步,所以速度相对ArrayList较慢。
4. Stack
数据结构:Object类型的动态数组
线程安全:线程安全
特点:元素先进(压栈)后出(出栈),类似手枪弹夹,默认容量为10,2倍扩容。
三、Map
1. TreeMap
数据结构:红黑树
线程安全:非线程安全
特点:1.元素添加顺序和排列顺序无关,键值不允许重复。
2.元素按键值排序,这个顺序需要我们自己指定(构造时传入比较器Comparator或让
元素实现Comparable接口重写compareTo方法)。
3.相对于HashMap统计性能更好,增、删、改、查性能较差。
2. HashMap
数据结构:动态数组 + 链表/红黑树
线程安全:非线程安全
添加元素:第一步:通过散列算法计算key值得出哈希值。
第二步:按照哈希值将元素放到指定的数组位置。
补充:如果两个不同的元素计算的哈希值相同,那么在数组中的位置就是一样的,
这两个元素就会自动组成一个链表,当链表容量大于8时,自动转换为红黑树。
特点:1.元素添加顺序和排列顺序无关,键值不允许重复。
2.元素按键值通过散列算法(哈希算法)算出的结果进行排序。
3.相对于TreeMap,增、删、改、查性能较好,统计性能较差。
3. LinkedHashMap
数据结构:动态数组 + 链表/红黑树 + 额外的顺序双链表
线程安全:非线程安全
特点:与HashMap特性一致,只是额外维护了一个双链表以记录元素顺序(支持插入顺序和访问顺序两种)
4. ConcurrentHashMap
数据结构:动态数组 + 链表/红黑树
线程安全:线程安全
特点:key和value不能为null
5. HashTable
数据结构:动态数组 + 链表
线程安全:线程安全
特点:key和value不能为null,官方已经不再建议使用,可以使用ConcurrentHashMap代替
四、Set
特点:元素不可重复
1. TreeSet
数据结构:红黑树 (底层为TreeMap)
线程安全:非线程安全
特点:1.元素添加顺序和排列顺序无关,值不允许重复。
2.元素按键值排序,这个顺序需要我们自己指定(构造时传入比较器Comparator或让
元素实现Comparable接口重写compareTo方法)。
2. HashSet
数据结构:动态数组 + 链表/红黑树 (底层HashMap)
线程安全:非线程安全
特点:1.元素添加顺序和排列顺序无关,值不允许重复。
2.元素按键值通过散列算法(哈希算法)算出的结果进行排序。
3. LinkedHashSet
数据结构:动态数组 + 链表/红黑树 (底层HashMap)
线程安全:非线程安全
特点:与HashSet特性一致,只是额外维护了一个双链表以记录元素添加顺序