HashMap
HashMap实现
HashMap默认的初始容积大小为16,加载因子默认为0.75,threslod阈值为:容积*加载因子
HashMao采用的链表法解决哈希冲突,同时引入红黑树可以避免单个链表长度过长的问题
- 默认值为8,将单向链表转换为红黑树,默认64,只有集合中的节点数大于64才可能进行树化处理
- 默认为6,红黑树退化为链表
Hash函数的设计需要考虑简单高校和分布均匀,所以首先获取对象的hashcode,然后将hah值的高位和低位进行与运算后,再针对数组长度进行求余
HashMap线程不安全,进行多线程操作时可能会出现扩容时执行rehash操作的死循环,脏读问题和size值不精确的问题
HashMap类定义
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>,Cloneable,Serializable{}
具体内存数据存储方式
transient Node<K,V>[] table;//哈希表的本质就是一个数组,数组中每个元素称为一个桶,桶中存放的键值对构成单向链表或者红黑树
transient定义数据的存储,但是HashMap又实现了序列化接口
private void writeObject(java.io.ObjectOUtputStream S) throws IOException
private void readObject(java.io.ObjectOUtputStream S) throws IOException, ClassNotFoundException
HashMap类提供序列化与反序列化操作的方法writeObject和readObject,以通告序列化处理的执行效率
重要阈值
static final int TREEIFY_THRESHOLD = 8;//树化阈值,链表转换为红黑树的阈值,当一个链表的元素个数大于8,会自动大于8,会自动将链表转换为红黑树
static final int UNTREEIFY_THRESHOLD = 6;//桶的红黑树退化为链表的还原阈值。当红黑树中节点数小于6,会自动将红黑树转换为链表
static final int MIN_TREEIFY_CAPACITY = 64;//最小树化处理的容积阈值,当哈希表中的容量大于64才允许进行树化处理
内部接口
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;//缓存的hash值
final K key;//具体存放的key值
V value;//具体存放数据的value值
Node<K,V> next;//单向链表
}
构造器
HashMap采用的是懒加载机制,构建HashMap对象时,并不直接构建数组,而是第一次添加元素时才会进行数组的初始化操作
public HashMap(){
this.loadFactor = DEFAULT_LOAD_FACTOR;
}
HashMap的无参构造器采用的是所有的默认值,容积是16,加载因子是0.75,扩容阈值threshold此时为12
Java允许在构建HashMap对象时,手动设置其初始化容积值initialCapacity
public HashMap(int initialCapacity){ this(initialCapacity,DEFAULT_LOAD_FACTOR); }