手机建设银行网站进不去,合理使用说明,网站建设 正邦,2015年做哪个网站致富Integer
位翻转
位翻转就是将二进制左边的位与右边的位进行互换#xff0c;reverse 是按位进行互换#xff0c; reverseBytes 是按 byte 进行互换。
public static int reverse(int i)public static int reverseBytes(int i)来看个例子#xff1a;
int a 0x12345678;
S…Integer
位翻转
位翻转就是将二进制左边的位与右边的位进行互换reverse 是按位进行互换 reverseBytes 是按 byte 进行互换。
public static int reverse(int i)public static int reverseBytes(int i)来看个例子
int a 0x12345678;
System.out.println(Integer.toBinaryString(a));
// 0001 0010 0011 0100 0101 0110 0111 1000int r Integer.reverse(a);
System.out.println(Integer.toBinaryString(r));
// 0001 1110 0110 1010 0010 1100 0100 1000int rb Integer.reverseBytes(a);
System.out.println(Integer.toHexString(rb));
// 0111 1000 0101 0110 0011 0100 0001 0010reverse 的实现
public static int reverse(int i) {//HD, Figure 7-1i (i 0x55555555) 1 | (i 1) 0x55555555;i (i 0x33333333) 2 | (i 2) 0x33333333;i (i 0x0f0f0f0f) 4 | (i 4) 0x0f0f0f0f;i (i 24) | ((i 0xff00) 8) |((i 8) 0xff00) | (i 24);return i;
}高效实现位翻转的基本思路是首先交换相邻的单一位然后以2位为一组再交换相邻的位接着是4位一组交换、然后是8位、16位16位之后就完成了。
i (i 0x55555555) 1 | (i 1) 0x55555555; 是对单一位进行翻转。 x 0x55555555 是取 x 的奇数位。 运算符的优先级比 | 运算符高。 i (i 0x33333333) 2 | (i 2) 0x33333333; 是以两位为一组对相邻位进行互换。 x 0x33333333 是取 x 以两位为一组的奇数位。 …
reverse 代码为什么不能用更容易理解的方式写吗比如实现翻转一种常见的思路是第一个和最后一个交换第二个和倒数第二个交换直到中间两个交换完成。如果数据不是二进制位这个思路是好的但对于二进制位这个思路的效率比较低。
CPU指令并不能高效地操作单个位它操作的最小数据单位一般是32位32位机器另外CPU可以高效地实现移位和逻辑运算但实现加、减、乘、除运算则比较慢。reverse是在充分利用CPU的这些特性并行高效地进行相邻位的交换可以通过其他更容易理解的方式实现相同功能但很难比这个代码更高效。
reverseBytes 的实现
public static int reverseBytes(int i) {return ((i 24))| ((i 8) 0xFF00)| ((i 8) 0xFF0000)| ((i 24));
}循环移位
Integer 有两个静态方法可以进行循环移位。
public static int rotateLeft(int i, int distance)
public static int rotateRight(int i, int distance)所谓循环移位是相对于普通的移位而言的普通移位比如左移2位原来的最高两位就没有了右边会补0而如果是循环左移两位则原来的最高两位会移到最右边。
源码实现
public static int rotateLeft(int i, int distance) {return (i distance) | (i -distance);
}public static int rotateRight(int i, int distance) {return (i distance) | (i -distance);
}令人费解的是负数如果 distance 是 8那 i-8 是什么意思呢
实际的移位个数不是后面的直接数字而是直接数字的最低 5 位的值之所以这样是因为 5 位最大表示 31移位超过 31 位对 int 整数是无效的。
valueOf
public static Integer valueOf(int i) {if (i IntegerCache.low i IntegerCache.high)return IntegerCache.cache[i (-IntegerCache.low)];return new Integer(i);
}IntegerCache表示Integer缓存其中的cache变量是一个静态Integer数组在静态初始化代码块中被初始化默认情况下保存了-128127共256个整数对应的Integer对象。
在valueOf代码中如果数值位于被缓存的范围即默认-128127则直接从Integer-Cache中获取已预先创建的Integer对象只有不在缓存范围时才通过new创建对象。
通过共享常用对象可以节省内存空间由于Integer是不可变的所以缓存的对象可以安全地被共享。
Character
Unicode
Unicode给世界上每个字符分配了一个编号编号范围为0x0000000x10FFFF。编号范围在0x00000xFFFF的字符为常用字符集称BMPBasic Multilingual Plane字符。编号范围在0x100000x10FFFF的字符叫做增补字符supplementary character。
Unicode主要规定了编号但没有规定如何把编号映射为二进制。UTF-16是一种编码方式或者叫映射方式它将编号映射为2个或4个字节对BMP字符它直接用两个字节表示对于增补字符使用4个字节表示前两个字节叫高代理项high surrogate范围为0xD8000xDBFF后两个字节叫低代理项low surrogate范围为0xDC000xDFFF。UTF-16定义了一个公式可以将编号与4字节表示进行相互转换。
Java内部采用UTF-16编码char表示一个字符但只能表示BMP中的字符对于增补字符需要使用两个char表示一个表示高代理项一个表示低代理项。
使用int可以表示任意一个Unicode字符低21位表示Unicode编号高11位设为0。整数编号在Unicode中一般称为代码点code point表示一个Unicode字符与之相对还有一个词代码单元code unit表示一个char。 参考《Java 编程的逻辑》马俊昌