示例图
-
List
ArrayList 是有序的 可重复,底层是使用了数组实现,特点就是查询快增删慢,线程不安全,默认的容量是10个元素如果超出这10个元素ArrayList就会以当前的容量*1.5+1进行扩容。Vector 是有序的 可重复,底层使用了数组实现,特点就是查询快增删慢,线程不安全,默认的容量是10个元素如果超出10元素Vectpr就会以当前的容量在增加1倍。
LinkedList 是有序的 可重复,底层是使用双向循环链表实现的,特点是增删快查询慢,线程安全,由于底层是使用双向链表实现所以就不用扩容。
-
Set
HashSet 是无序的,索引唯一,底层是使用Hash表实现,特点就是存取速度快,线程不安全,默认的容量是16个元素如果超出当前元素HashSet就会以当前的容量扩容1倍。TreeSet 是默认的排序,元素唯一,底层使用的是二叉树实现的,线程不安全。
LinkedHashSet 是无序的,索引唯一,底层不只有父类的Hash存储结构,自身还保存着双向循环链表的插入顺序。
-
Map
HashMap 键为一,值可重复,底层是Hash表实现,线程不安全,默认的容量是16个元素当容量超出时HashMap会以当前的容量的2倍扩容,特点是它的键可为null值也可以为null但是键只能有一次为null。HashTable 键唯一,值可重复,底层是Hash表实现,默认的容量是11个元素当超出当前容量时HashTable会以当前的容的2倍+1进行扩容,线程是安全的但是它的键和值都不可以为null。
TreeMap 键为一,值可重复,底层使用的是二叉树实现。
结构特点
- List 和 Set 是存储单列数据的集合,Map 是存储键和值这样的双列数据的集合
- List 中存储的数据是有顺序,并且允许重复
- Map 中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的
- Set中存储的数据是无序的,且不允许有重复,但元素在集合中的位置由元素的 hashcode 决定,位置是固定的(Set 集合根据 hashcode 来进行数据的存储,所以位置是固定的,但是位置不是用户可以控制的,所以对于用户来说 set 中的元素还是无序的)
HashMap 和 HashTable 有什么区别?
- HashMap 是线程不安全的,HashMap 是一个接口,是 Map 的一个子接口,是将键映射到值得对象,不允许键值重复,允许空键和空值;由于非线程安全,HashMap 的效率要较比 HashTable 的效率高一些
- HashTable 是线程安全的一个集合,不允许键或值为 null
- HashTable 是 sychronize,多个线程访问时不需要自己为它的方法实现同步,而 HashMap 在被多个线程访问的时候需要自己为它的方法实现同步否则会导致数据不一致
HashMap底层实现原理
-
HashMap根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值.因而具有很快的访问速度,但是遍历顺序却不确定的.HashMap最多只允许一条记录的键为null,允许多条记录的值为null,HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。
-
JDK1.8之后HashMap底层(数组+链表+红黑树)
如果链表的长度超过8则转为红黑树, 当红黑树中的元素小于6时又变为链表
哈希表存储逻辑
- 首先根据每个元素的哈希值去和数组的长度取余,而余数就是数组的下标,如果当前元素的存储下标已经存储元素,就和当前下标下的元素hash值比较,如果不相等就存储到该索引下的链表内,如果相同的hash值则替换不相等就用equals判断该元素的内容是否相等相等就替换
个人笔记收集,觉得重要的点就会记录,后续更新