1、 基础认知
HashMap是由数组和链表组合构成的数据结构。
默认负载因子 loadFactor 负载因子,默认值0.75f
默认初始化长度 16
链表存储模型:
java8中引入
- 存储元素小于等于6时为链表
- 元素为7时不做改变
- 元素为8时变为红黑树
因为他本身所有的位置都为null,在put插入的时候会根据key的hash去计算一个index值。
数据本身是通过key值得hash值来进行存储,虽然hashmap提供的是散列存储 意思是使数据均匀的分布在不同的hash位置上 但实际场景中还是有很多key值是属于同一个hash值下的 意思就是存储在数组的同一个位置上 而在这个位置上存储的就是一个链表 在查询时 会先通过key值得hash值 找到hash值所在的链表 然后在链表上递归查询出对应的值
HashMap中存储的每个元素 都是存储在一个Node<K, V>对象中的 在这个对象中会存储 key的hash值 key值 value值及下一个元素 所以hashmap中的链表是一个单向链表
2、 链表插入方法
java8之前是头插法,就是说新来的值会取代原有的值,原有的值就顺推到链表中去,就像上面的例子一样,因为写这个代码的作者认为后来的值被查找的可能性更大一点,提升查找的效率。
但是,在java8之后,都是所用尾部插入了。
但是为什么会有存头存尾的改变呢?
首先要看一下HashMap如何扩容
扩容发生的前提由两个参数影响 一个是capacity容量,LoadFactor负载因子,默认值0.75f
意思就是 如果一个容量为100的map,当你存入第76个的时候就需要扩容了 也就是resize
扩容主要分为两步
- 扩容