开篇废话
运算符使用的几点小技巧,先给出Java的运算符的基本知识复习下,其它语言的大同小异。运算符需要注意的问题有:优先级(运算顺序问题)、结合方向(自左至右或自右至左问题)、要求运算对象个数(运算符需要有几个运算对象问题)。
合理运用运算符能提高自己代码的BIG、能精简代码、还能提高程序的运行效率,滥用运算符可能导致逻辑混乱、代码不知所云什么的,所以有些问题还是要自己注意一下的。下面就列出一些运算符的使用技巧,换一换思路看下,当然还有先占着这个坑,以后会补(man)上(man)更(lai)新(ba)。
^ 按位异或
不用第三个临时变量交换两个数的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static void main(String[] args) { int a = 2; // int a = -2; int b = 3; /* 总的来说就是先找出两个数上位值不同的位置置1其余0,然后将得到的新值分别和a、b的原值异或 */ a ^= b; // a = a ^ b; b ^= a; // b = a ^ b; a ^= b; // a = a ^ b; System.out.printf("交换后: a=%s, b=%s", a, b); } ``` ## <<、>> 按位左移、右移 ### 将一个数乘于2的n次方a*(2<sup>n</sup>) ``` Java int a = 2; int n = 3; // n=1, 左移一位就是乘于2 a <<= n; // a = a << n; System.out.println("a*(2^n) = " + a);
|
将一个数除以2的n次方a/(2n)
1 2 3 4 5 6 7 8 9 10 11 12 13
| int a = 32; int n = 3; //n=1, 右移一位就是除于2 a >>= n; // a = a >> n; System.out.println("a/(2^n) = " + a); ``` <!--more--> ### 2的n次方 ``` Java int n = 3; // int n = 0; int result = 2 << (n - 1); System.out.println("2^n = " + result);
|
& 按位与
判断一个数的奇偶
1 2 3
| int a = 3; boolean bl = (a & 1) == 1; System.out.println("a为奇数? " + bl);
|
对2n取余
1 2 3 4 5
| int n = 2 << 2; int value = 2; int result = value & (n - 1); System.out.println("2对8取余接结果 = " + result);
|
HashMap的table的大小(HashMap的优化是把hash表的大小设置为2n的)和确定元素的存放位置即table表中的位置(indexFor(int h, int length)
方法)也是运用了这一原理,HashMap相关代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
| * The table, resized as necessary. Length MUST Always be a power of two. */ transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE; ...... * Returns index for hash code h. */ static int indexFor(int h, int length) { return h & (length-1); }
|
HashMap中hash(Object k)
函数也运用了int类型(4个字节32位)数据的按位右移补零(>>>)和异或(^)运算加入了高位计算,防止低位不变,高位变化时,造成的hash冲突也就是要使得高位对其结果也产生影响:
1 2 3 4 5
| h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4);
|
END
参考文章:
优秀程序员不得不知道的20个位运算技巧
Java HashMap 核心源码解读
JAVA移位运算符
最后更新时间:
除特别说明外,文章均采用「知识共享 署名 - 非商业性 - 相同方式共享 4.0 协议」进行许可,转载需注明文章出处:
https://rocko.xyz/2015/01/14/运算符的几点/