java怎么打2的幂数_关于JDK1.8 java HashMap的tableSizeFor的解析:一个数最近2的幂次数方法...

简介

一个数的最近2的幂次数,是java hashmap初始化方法指定容量里面对容量进行处理采用的方法

1.位运算符号介绍

符号

描述

运算规则

&

两个位都为1时,结果才为1

|

两个位都为0时,结果才为0

^

异或

两个位相同为0,相异为1

~

取反

0变1,1变0

<<

左移

各二进位全部左移若干位,高位丢弃,低位补0

>>

右移

各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

>>>

无符号右移

在右移的基础上,高位补0,无论有符号数还是无符号数

<<<

没有

没有无符号左移

2.JDK1.8中hashmap的tableSizeFor源码,如下

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;

}

测试

public static void main(String[] args) {

hightwo(0);

hightwo(7);

hightwo(32);

}

private static void hightwo(int cap) {

int n = cap - 1;

n |= n >>> 1;

n |= n >>> 2;

n |= n >>> 4;

n |= n >>> 8;

n |= n >>> 16;

System.out.println((n<0) ? 1 : (n+1));

}

结果:

6d7913405553b663a37c672369f5b4f8.png

解析:计算容量,通过参数中指定的容量,得到离2的n次幂最近的数返回(数大于等于原来输入cap)

思路:先将cap的低位全变1,之后再+1,使低位进位变0,高位变1

举例cap为7

cap:7 二进制 0000 0111

n cap-1 6 0000 0110

0000 0011 n>>>1

0000 0110 n

==================

0000 0111 n|n>>>1

0000 0001 n>>>2

0000 0111

==================

0000 0111 n|n>>>2 低位全为1,后续操作结果一样

...

n 0000 0111 7

cap = n+1 = 8

问题:关于为什么cap首先减1?

回答:防止本来就是2的次幂数返回2倍,比如cap是8,若不减1,则返回16而不是8了

举例

cap 8

0000 1000

0000 0100 n>>>1

===================

0000 1100 n|n>>>1

0000 0011 n>>>2

0000 1100

====================

0000 1111 n|n>>>2 低位全为1,后续操作结果一样

0000 0001 n+1

=====================

0001 0000 16

cap = 15 + 1 = 16

3.其它

一个数的最近2的幂次数(小于等于原数)

private static int lowtwo(int n) {

n |= n >>> 1;

n |= n >>> 2;

n |= n >>> 4;

n |= n >>> 8;

n |= n >>> 16;

n -= n>>>1;

return (n <= 0) ? 1 : n;

}

思路:将cap低位变1,再无符号右移1位,cap再减之,将低位变0,高位保留

测试

public static void main(String[] args) {

System.out.println(lowtwo(0));

System.out.println(lowtwo(7));

System.out.println(lowtwo(32));

}

private static int lowtwo(int n) {

n |= n >>> 1;

n |= n >>> 2;

n |= n >>> 4;

n |= n >>> 8;

n |= n >>> 16;

n -= n>>>1;

return (n <= 0) ? 1 : n;

}

/*结果*/

1

4

32

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值