HashMap要点

前言

Java集合当中HashMap应该是尤为突出的,使用频繁,实现机制巧妙。想要通过看源码了解所有实现原理需要有很深度的基础功底,鄙人不才只看懂1、2,这里主要以jdk1.8为例,将看懂的做个总结。

jdk怎么说?

在这里插入图片描述

精妙之处

关键变量

DEFAULT_INITIAL_CAPACITY 默认table数组大小16(根据实际情况可调整)
DEFAULT_LOAD_FACTOR 默认装载因子0.75
TREEIFY_THRESHOLD 默认链表转树链表长度阈值之一8
UNTREEIFY_THRESHOLD 默认树转链表阈值6
MIN_TREEIFY_CAPACITY 默认链表转树数组长度阈值之二64

数据结构

hashMap底层数据结构是数组+链表(到达阈值升级为红黑树),结构体为:

Node<K,V> implements Map.Entry<K,V> {
		//hash值
        final int hash;
        final K key;
        V value;
        //链表结构,下一个节点的指针
        Node<K,V> next;
     }

table为此数据结构的引用:transient Node<K,V>[] table;
这里还有一点就是table的长度为2的整数次幂,在创建HashMap时如果初始化长度不是2的整数次幂,也会向上取整转为2的整数次幂,比如new HashMap(10),其实初始化结果为16。这个时怎么做到的呢?如下代码:

static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

key值hash算法

当插入一条记录时,首先做的就是计算key的hash值计算,代码如下:

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

(h = key.hashCode()) ^ (h >>> 16)代码的实质为:将hashcode返回的是32位的整型中的高16位和低16进行异或操作,并且高16不变,这样操作有几点优势:

  1. 位运算效率肯定要比取模高
  2. 可以是key分布均匀减少hash冲突

扩容机制

HashMap在什么情况下会进行扩容?在什么情况下会进行链表转红黑树呢?
扩容有两种情况:

  1. 当table数组的容量 > table数组的长度 * 扩容因子
  2. 当链表长度 >= TREEIFY_THRESHOLD(这里以默认值为例) && table数组长度 < MIN_TREEIFY_CAPACITY(这里以默认值为例)

链表转红黑树的条件也就出来了:
当链表长度 >= TREEIFY_THRESHOLD(这里以默认值为例) && table数组长度 >= MIN_TREEIFY_CAPACITY(这里以默认值为例)

当容量扩完之后会进行resize()操作,即将原来table中的数据迁移到新的table中,其中会对key进行重新hash:

newTab[e.hash & (newCap - 1)] = e;

如果是链表的话此行代码限制了新的hash值只可能为原来值或者为原来+原table长度。

未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值