Integer 原码解读
有一天,突然发现,阅读原码可以发现很多有趣的东西。在Java中,我们知道很多东西都是封装好的,拿来即用,当你有一天去研究它拿来的东西是如何具体操作的,将会是非常有趣的事情。
在上一篇研究HashMap 源码的时候,发现了将任意大于某个数字的最小二次幂的实现,发现别人写的不仅漂亮而且高效。
在Java 的底层,很多高效的算法包含其中,阅读源码是非常有帮助的。
接下来将开始阅读 Integer 的源码,让自己更多的理解Integer 这个类的实现。
一.Integer 中的进制转换,包括将十进制转换为二进制及、八进制、十六进制
1.调用方法
Integer.toBinaryString()
Integer.toOctalString()
Integer.toHexString()
2.实现方法
转换为二进制
public static String toBinaryString(int i) {
return toUnsignedString0(i, );
} 转换为八进制
public static String toOctalString(int i) {
return toUnsignedString0(i, );
} 转换为十六进制
public static String toHexString(int i) {
return toUnsignedString0(i, );
}
3.底层实现
发现所有的进制转换都是调用的 toUnsignedString0() 这个方法,其实现如下
方法调用一
private static String toUnsignedString0(int val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - )) / shift), );
char[] buf = new char[chars]; formatUnsignedInt(val, shift, buf, , chars); // Use special constructor which takes over "buf".
return new String(buf);
} 方法调用二
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
int charPos = len;
int radix = << shift;
int mask = radix - ;
do {
buf[offset + --charPos] = digits[val & mask];
val >>>= shift;
} while (val != && charPos > ); return charPos;
} 方法调用三
final static char[] digits = {
'' , '' , '' , '' , '' , '' ,
'' , '' , '' , '' , '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'
};
二. Integer 中的方法
方法1:比较2个数字的大小,若 第一个小于第二个,返回-1;若相等,返回0;若第一个大于第二个,返回1
public static int compare(int x, int y) {
return (x < y) ? - : ((x == y) ? : );
}
方法2: 返回该数字二进制 补码中 1 的个数
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> ) & 0x55555555);
i = (i & 0x33333333) + ((i >>> ) & 0x33333333);
i = (i + (i >>> )) & 0x0f0f0f0f;
i = i + (i >>> );
i = i + (i >>> );
return i & 0x3f;
}
方法3: 返回String 或者 int 类型的 Integer 实例
第一步:
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, ));
} 第二步:
public static int parseInt(String s, int radix)
throws NumberFormatException
{
/*
* WARNING: This method may be invoked early during VM initialization
* before IntegerCache is initialized. Care must be taken to not use
* the valueOf method.
*/ if (s == null) {
throw new NumberFormatException("null");
} if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
} if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
} int result = ;
boolean negative = false;
int i = , len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit; if (len > ) {
char firstChar = s.charAt();
if (firstChar < '') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s); if (len == ) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < ) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
} 第三步:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
方法4:将String 类型转换为 Int 类型
输入String
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,);
} parseInt() 调用方法同上
Integer 原码解读的更多相关文章
- python skimage库HOG特征提取原码解读
Hog特征+SVM常用来做行人检测. opencv中也有Hog特征提取的原码,但是由于原码不是用python写的,而skimage用python实现了,所以就解读的skimage的代码. 先看用ski ...
- task_struct原码解读
该结构体在linux中的路径为如下,如果是本地也可以根据以下子目录找到task_struct结构体,该结构体源码中在600多行 https://github.com/torvalds/linux/bl ...
- 进制,原码VS补码
进制 十,八,十六进制=>二进制 十进制=>二进制:辗转相除取余,10除2商5余0,5除2商2余1,2除2商1余0,1除2商0余1,So,10d=1010b 八进制=>二进制:每1位 ...
- 【原】Spark不同运行模式下资源分配源码解读
版权声明:本文为原创文章,未经允许不得转载. 复习内容: Spark中Task的提交源码解读 http://www.cnblogs.com/yourarebest/p/5423906.html Sch ...
- 【原】Spark中Job的提交源码解读
版权声明:本文为原创文章,未经允许不得转载. Spark程序程序job的运行是通过actions算子触发的,每一个action算子其实是一个runJob方法的运行,详见文章 SparkContex源码 ...
- 【原】SparkContex源码解读(二)
版权声明:本文为原创文章,未经允许不得转载. 继续前一篇的内容.前一篇内容为: SparkContex源码解读(一)http://www.cnblogs.com/yourarebest/p/53266 ...
- jdk1.8.0_45源码解读——ArrayList的实现
jdk1.8.0_45源码解读——ArrayList的实现 一.ArrayList概述 ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包括 null 在内的所有元素. ...
- MyBatis源码解读之延迟加载
1. 目的 本文主要解读MyBatis 延迟加载实现原理 2. 延迟加载如何使用 Setting 参数配置 设置参数 描述 有效值 默认值 lazyLoadingEnabled 延迟加载的全局开关.当 ...
- JDK容器类List,Set,Queue源码解读
List,Set,Queue都是继承Collection接口的单列集合接口.List常用的实现主要有ArrayList,LinkedList,List中的数据是有序可重复的.Set常用的实现主要是Ha ...
随机推荐
- 【转】netstat 的10个基本用法
5. 获取进程名.进程号以及用户 ID 查看端口和连接的信息时,能查看到它们对应的进程名和进程号对系统管理员来说是非常有帮助的.举个栗子,Apache 的 httpd 服务开启80端口,如果你要查看 ...
- 15.unbuntu下安装vmware-tools
链接地址:https://blog.csdn.net/yuanxiang01/article/details/78787823
- 37. sqlplus工具连接服务端或其他电脑的oracle方式
1. 方式1:IP:监听端口/实例ID,例如:192.168.0.1:1521/orcl 2.方式2:IP:监听端口/服务名,例如:192.168.0.1:1521/ORCL.168.0.1 查看服务 ...
- leetcode1023
class Solution(object): def getGroup(self,que): group = list() temp = '' for i in range(len(que)): c ...
- linux 显示系统执行的进程
ps -a 显示所有的进程信息 -u 以用户的形式显示系统进程 -x 显示后台进程运行的参数 netstat -anp |more 查看端口 查看开放的端口 vim/etc/sysconfig/ ...
- 20165304 实验二 Java面向对象程序设计
一.面向对象程序设计1--单元测试和TDD 实验要求 1.参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECUNITTEST 完成单元测试的学习 2 ...
- APP-8.1-百度语音应用
1.百度语音登录地址 http://yuyin.baidu.com/ 2.控制台创建应用 3.生成签名 3.1Postman软件应用 APP-8.2-Postman应用 3.2Postman执行 UR ...
- cx_Oracle.DatabaseError: DPI-1047
ODPI-C Installation¶ Overview Oracle Client and Database Versions Linux Oracle Instant Client Zip Or ...
- HTML Tags
While some tags have a very specific purpose, such as image and video tags, most tags are used to de ...
- docker之container
转自:https://www.cnblogs.com/jsonhc/p/7760144.html 运行一个container的本身就是开启一个具有独立namespace的进程 进程有自己的网络,文件系 ...