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 ...
随机推荐
- C++ Sleep() sleep()
简介: 函数名: sleep 功 能: 执行挂起一段时间 用 法: unsigned sleep(unsigned seconds); 在VC中使用带上头文件 #include <windows ...
- 使用DolphinPHP的框架中的excel插件导入数据
直接上函数吧 public function importfile() { if ($this->request->isPost()) { if($_POST['files']) { Cu ...
- 4.HTML+CSS制作个月亮
效果地址:https://codepen.io/flyingliao/pen/LaRmJr?editors=1100 感想:还有缺陷,需后期补充.完善. HTML code: <div clas ...
- 2.HTML文件中<!DOCTYPE html>的作用
<!DOCTYPE> 声明位于文档中的最前面的位置,处于 <html> 标签之前.此标签可告知浏 览器文档使用哪种 HTML 或 XHTML 规范.(重点:告诉浏览器按照何种规 ...
- Ignoring query to other database
Ignoring query to other database 自己今天刚遇到,进入MySQL的时候,输入show databases; 产生如下错误 错误提示 Ignoring query to ...
- Jquery的一些基本操作
/*获得TEXT.AREATEXT的值*/ var textval = $("#text_id").attr("value"); //或者 var textva ...
- Django 之多表查询 与多表的使用
1.django的多表查询 主要区分为: 正向查询 逆向查询 1. 多表查询: 是一个复杂的查询,他分为对象查询和__模糊查询两种方式 2. 多表查询: 又分为 一对一查询, 一对多查询, 多对 ...
- word中怎样设置页码包含总页数
一个同事做毕业论文,论文是Word格式,1-2页是封面和目录,不需要页码,第3-10页是论文内容,需要从第1页开始显示,并显示论文内容的总页数8 页.具体为页脚处显示“第*页共*页”.他让我帮忙设置一 ...
- c# sql等微型代码工具LinqPad
- Yum安装MySQL以及相关目录路径和修改目录
有些时候,为了方便,有些同学喜欢通过yum的方式安装MySQL,没有设置统一的文件目录以及软件目录,那么就会为后续的维护工作带来很大的麻烦! 下面就简单介绍一下yum安装MySQL的步骤以及这类安装下 ...