今天,在编写一段程序时需要将byte类型的数据,用“二进制”形式的字符串输出,冥思苦想也不知道如何入手。忽然灵机一动记得Java中的Integer包装器类有一个toBinaryString(int i)以二进制(基数2)无符号整数形式返回一个整数参数的字符串表示形式的方法。
查找
Java源代码文件
Integer.java找到方法源码如下:
public
static
String toBinaryString(
int
i)
...
{
return toUnsignedString(i, 1);
}
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
实际上调用的是
toUnsignedString(i, 1);
方法
,
再继续查找源码如下:
/** */
/**
* Convert the integer to an unsigned number.
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
private
static
String toUnsignedString(
int
i,
int
shift)
...
{
char[] buf = new char[32];
int charPos = 32;
int radix = 1 << shift;
int mask = radix - 1;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
do ...{
buf[--charPos] = digits[i & mask];
i >>>= shift;
} while (i != 0);
return new String(buf, charPos, (32 - charPos));
}
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
其中,方法中需要使用的数组
digits[]定义如下:
final
static
char
[] digits
=
...
{
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
'o' , 'p' , 'q' , 'r' , 's' , 't' ,
'u' , 'v' , 'w' , 'x' , 'y' , 'z'
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
好了,源码已经找到了。现在就开始分析
Java类库的设计师们是如何实现它的吧。假设我们这样调用
toUnsignedString(5, 1);
方法。
1)
char[] buf = new char[32];
//
创建一个char型数组长度32(int型数据在java中是32位的)存放计算后数据。
2)
int charPos = 32;
//
计数器
int radix = 1 << shift; // 注意这个地方1是个整型值(32位),它被左移了1位右边空出的用0补充,然后再赋值给了radix。下图是左移前与左移后数据1的二进制表式图:
4) int mask = radix - 1;
关键算法如下:
5) do {
6) buf[--charPos] = digits[i & mask];
7) i >>>= shift;
8) } while (i != 0);
6) buf[--charPos] 因为数组下标是从0开始的,所以起始索引为31(对应内存中的第32位)。digits[i & mask]内存表示图如下:
int radix = 1 << shift; // 注意这个地方1是个整型值(32位),它被左移了1位右边空出的用0补充,然后再赋值给了radix。下图是左移前与左移后数据1的二进制表式图:
4) int mask = radix - 1;
关键算法如下:
5) do {
6) buf[--charPos] = digits[i & mask];
7) i >>>= shift;
8) } while (i != 0);
6) buf[--charPos] 因为数组下标是从0开始的,所以起始索引为31(对应内存中的第32位)。digits[i & mask]内存表示图如下:
7)i>>>=shift;
8) } while (i != 0);//i=2 != 0循环继续5-7步,直至i=0结束循环至此程序运行结束。
9)return new String(buf, charPos, (32 - charPos));//调用String类的构造函数,创建一个指定字符数组的字符串对像,程序看到这里问题已经得到解决,下面的代码我就不深究了如果大家感兴趣可以去看源代码。
总结:研究了Java源代码后对toBinaryString(int i)方法有了更深入的了解, Java库设计师们通过空间来换取速度,不过想想这种浪费空间的方法还是值得的。当然解决问题方法不仅仅只有这一种。