美文网首页
Java8—HashMap之tableSizeFor()

Java8—HashMap之tableSizeFor()

作者: 草捏子 | 来源:发表于2017-10-10 13:44 被阅读131次

看HashMap的源码时,发现了里面好多很不错的算法。
tableSizeFor的功能(不考虑大于最大容量的情况)是返回大于输入参数且最近的2的整数次幂的数。比如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;
}

详解如下:

先来分析有关n位操作部分:先来假设n的二进制为01xxx...xxx。接着

对n右移1位:001xx...xxx,再位或:011xx...xxx

对n右移2为:00011...xxx,再位或:01111...xxx

此时前面已经有四个1了,再右移4位且位或可得8个1

同理,有8个1,右移8位肯定会让后八位也为1。

综上可得,该算法让最高位的1后面的位全变为1。

最后再让结果n+1,即得到了2的整数次幂的值了。

由于int是32位,所以>>>16便能满足。

举个栗子.jpg

现在回来看看第一条语句:

int n = cap - 1;

让cap-1再赋值给n的目的是另找到的目标值大于或等于原值。例如二进制1000,十进制数值为8。如果不对它减1而直接操作,将得到答案10000,即16。显然不是结果。减1后二进制为111,再进行操作则会得到原来的数值1000,即8。

HashMap里的MAXIMUM_CAPACITY是230。我结合tableSizeFor()的实现,猜测设置原因如下:
int的正数最大可达231-1,而没办法取到231。所以容量也无法达到231。又需要让容量满足2的幂次。所以设置为230

相关文章

  • HashMap

    Java8 HashMap结构 构造方法 threshold = tableSizeFor(initialCapa...

  • Java8—HashMap之tableSizeFor()

    看HashMap的源码时,发现了里面好多很不错的算法。tableSizeFor的功能(不考虑大于最大容量的情况)是...

  • Java8 HashMap之tableSizeFor

    推荐:https://www.cnblogs.com/loading4/p/6239441.html

  • HashMap之tableSizeFor方法

    tableSizeFor方法 HashMap内部的数组大小强制为2的幂次方,这样在根据key的hash值通过按位与...

  • 每周阅读(6/27)

    HashMap的实现和原理,如何运用红黑树实现扩容优化。Java8系列之重新认识HashMap Google的代码...

  • HashMap中的tableSizeFor

    用于返回一个比给定整数大且最接近的2的幂次方整数 右移1位再与移动前数字逐位异或,可以保证最高位和次高位均为1,结...

  • Java8 HashMap源码解析

    Java8 HashMap Java8 在 Java7 的基础上对 HashMap 进行优化,由数组+链表结构,改...

  • HashMap分析(转)

    本文转自美团点评的[java8系列之重新认识HashMap] (https://tech.meituan.com/...

  • HashMap 源码 - tableSizeFor(int ca

    核心思想 第一个大于或等于 cap 的 2 的幂次方数为,将二进制的 cap 的第一个 1 之后的所有 bit 置...

  • HashMap里面的一个细节

    扫了一眼Java8的HashMap的代码,发现一个细节,觉得值得一记。 我们知道Java8里面的HashMap做了...

网友评论

      本文标题:Java8—HashMap之tableSizeFor()

      本文链接:https://www.haomeiwen.com/subject/fqpvyxtx.html