HashMap

基础入门

  • 散列表数据结构:散列表是一个基于线性表和链表的优点和长度于一身的数据结构。其实就是一个数组,然后数组里面保存的数据是一个个的链表。
  • 什么是哈希:Hash也称散列,基本原理就是将任意长度的输入转化为固定长度的输出。哈希算法是单向的,不可逆的。哈希算法的冲突概率很小。但是根据抽屉原理,一定会存在不同的输入被映射为相同的输出的情况。

HashMap原理

  • HashMap的继承体系:先继承了Map的一个抽象类AbstractMap,然后实现了AbstractMap。

Node数据结构分析

    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;
  • Node<K,V> next作用:hashMap的存放类似于散列表,并且因为hash值有碰撞,如果碰撞的话就会在数组的同一个位置用链表来进行存储。

底层存储结构的介绍

  • 外部是一个Node数组,默认初始化长度为16,而且数组的长度一定是2的N次方. static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
  • 当发生碰撞的时候,数组里面存放的会自动转变为链表。
  • 当链表的长度超过8,并且数组长度达到64个的时候,整个链表会转变为红黑树。(java8新特性)
static final int TREEIFY_THRESHOLD = 8;
static final int MIN_TREEIFY_CAPACITY = 64;

put过程介绍

  • 可以看出,其实HashMap本质上就是计算出Key的hash值,然后通过一次扰动函数使其更加散列,之后再通过取余的运算添加到相应数组的位置上。
  • 使用hash值得原因可能是因为Key和Value都可以使用字符串得缘故。

JDK8为何引用红黑树

  • 当数据非常多的时候,难免会出现哈希碰撞的问题,而出现哈希碰撞之后就会链化。
  • 当链足够长的时候,其实查找效率就会变得非常的低下,因为本身数组查找的时间复杂度是O(1),而链表则是O(N)
  • 为了优化链表的查找效率,引入了红黑树的数据结构。

HashMap的扩容原理

  • 扩容就是增加数组的长度。
  • 数组的长度增加,Hash碰撞的次数就会减少,相对来讲也会减少非常多的链表长度。可以起到降低时间复杂度的作用。

源码分析

  • 几个常量
/**
 * 默认的初始化数组长度 2的4次方
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

/**
 * 默认的最大数组长度 2的30次方
 */
static final int MAXIMUM_CAPACITY = 1 << 30;

/**
 * 默认的负载因子
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;

/**
 * 树化阙值,如果链表长度达到8,就有可能转为红黑树
 */
static final int TREEIFY_THRESHOLD = 8;

/**
 * 树降级称为链表的阈值
 */
static final int UNTREEIFY_THRESHOLD = 6;

/**
 * 当数组的长度超过64之后,才有可能转化为树
 */
static final int MIN_TREEIFY_CAPACITY = 64;

  • 几个属性
/**
 * 哈希表,可以看出hash表是一个Node数组
 */
transient Node<K,V>[] table;

/**
 * Holds cached entrySet(). Note that AbstractMap fields are used
 * for keySet() and values().
 */
transient Set<Map.Entry<K,V>> entrySet;

/**
 * hash表的大小
 */
transient int size;

/**
 * 当前hash表的修改次数
 * /
transient int modCount;

/**
 * 扩容阙值,当你的hash表中的元素超过阙值的时候,触发扩容
 */
int threshold;

/**
 * 负载因子
 * threshold = capacity * loadFactor
 */
final float loadFactor;
posted @ 2021-03-04 01:33  一个汉服程序员苏木  阅读(62)  评论(0)    收藏  举报