简单示意图
详细示意图
ArrayList 和 LinkedList 区别
- ArrayList(默认size为10) 是实现了基于动态数组的数据结构,LinkedList 基于双向链表的数据结构。
- 对于随机访问 get 和 set,ArrayList 效率优于 LinkedList,因为 LinkedList 要移
动指针。 - 对于新增和删除操作 add 和 remove,LinkedList 比较占优势,因为 ArrayList 要
移动数据。 这一点要看实际情况的。若只对单条数据插入或删除,ArrayList 的速度反
而优于 LinkedList。但若是批量随机的插入删除数据,LinkedList 的速度大大优于
ArrayList. 因为 ArrayList 每插入一条数据,要移动插入点及之后的所有数据。
HashMap
HashMap 继承了 AbstractMap 抽象类,而 AbstractMap 实现了 Map 接口,是一个 K,V 存储方式,允许 nullKey nullValue
在 JDK8 中,底层实现方式是数组+链表或红黑树,在默认情况下创建 HashMap 它的 size 为 16,负载因子默认为 0.75,当链表长度大于 8,并且数组长度大于 64 时,链表转为红黑树。当链表长度小于等于 6 时,转为链表 数组扩容机制,是根据负载因子计算的,当动态数组存储数量>=负载因子 * size 则进行翻倍扩容
如何解决 hash 碰撞:也就是刚才说的链表或红黑树,每一个数组位置都相当于一个 bucket,每个 bucket 都会存储多个 Node 节点,而这个 Node 又实现了 Entry,这个类都是 HashMap 的内部类,他们的类中都包含了, hash 值、key 值、value 值、next 节点,如果出现 hash 碰撞我们会在同一个 bucket 中存储多个 Node
如何 get 到 HashMap 的一个 key,首先我们会根据 key 值计算出一个 hash 位置,找到对应的 bucket,接着我们根据 key 来遍历该 bucket 中的链表或红黑树,直到找到相应的 Node 并返回
HashSet
HashSet 的内部采用 Hash Map 来实现。 由于 Map 需要 key 和 value ,所以所有 key
都有一个默认 value。类似于 Hash Map ,HashSet 不允许重复的 key ,只允许有一个 null key ,
意思就是 HashSet 中只允许存储一个 null 对象。