HashMap源码理解

HashMap如何put数据(从HashMap源码角度讲解)

HashMap怎么手写实现

 

HashMap有两个影响性能的重要参数:初始容量和加载因子。容量是Hash表中桶的个数,当HashMap初始化时,容量就是初始容量。加载因子是衡量hash表多满的一个指标,用来判断是否需要增加容量。当HashMap需要增加容量时,将会导致rehash操作。

默认情况下,0.75的加载因子在时间和空间方面提供了很好的平衡。加载因子越大,增加了空间利用率但是也增加了查询的时间。

在JDK1.7之前,HashMap采用的是数组+链表的结构,其结构图如下: 

HashMap源码理解_第1张图片

左边部分代表Hash表,数组的每一个元素都是一个单链表的头节点,链表是用来解决冲突的,如果不同的key映射到了数组的同一位置处,就将其放入单链表中。

 

JDK1.8的结构

JDK1.8之前的HashMap都采用上图的结构,都是基于一个数组和多个单链表,hash值冲突的时候,就将对应节点以链表形式存储。如果在一个链表中查找一个节点时,将会花费O(n)的查找时间,会有很大的性能损失。到了JDK1.8,当同一个Hash值的节点数不小于8时,不再采用单链表形式存储,而是采用红黑树,如下图所示:

HashMap源码理解_第2张图片

HashMap中有几个重要的字段,如下:

    //Hash表结构
    transient Node[] table;

    //元素个数
    transient int size;

    //确保fail-fast机制
    transient int modCount;

    //下一次增容前的阈值
    int threshold;

    //加载因子
    final float loadFactor;

     //默认初始容量
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

   //最大容量
    static final int MAXIMUM_CAPACITY = 1 << 30;

    //加载因子
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    //链表转红黑树的阈值
    static final int TREEIFY_THRESHOLD = 8;

 

HashMap一共有4个构造方法,主要的工作就是完成容量和加载因子的赋值。Hash表都是采用的懒加载方式,当第一次插入数据时才会创建。

 

源码看容器系列的HashMap分析

 

你可能感兴趣的:(Java容器)