java--学习Integer源码(慢慢补)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java--学习Integer源码(慢慢补)相关的知识,希望对你有一定的参考价值。

今天不看spring了,上了一天的课,晚上还要写编译原理作业(头疼)。先看点api的源码放松一下。不得不说,看这些世界上最顶尖的程序员写出来的东西真是和看nba一样是一件愉快的事情,虽然有点烧脑。

先看看Integer.toString(int i)是怎么实现的。

首先有两个相关的方法,stringSize(int x)和getChars(int i, int index, char[] buf).

1 final static int [] sizeTable = {9,99,999,9999,99999,999999,9999999,99999999,999999999,Integer.MAX_VALUE};
2 static int stringSize(int x) {
3   for(int i=0; ;i++)
4     if(x<= sizeTable[i])
5         return i+1;
6 }

原来确定一个数字的位数是这么玩的,简直厉害哭了;突然想起自己以前的不断除10,简直脸红。忍不住临摹了一遍。

 1 static void getChars(int i, int index, char[] buf) {    
 2     int q,r;
 3     int charPos = index;
 4     char sign =0;
 5     if(i < 0) {    
 6         sign = ‘-‘;
 7         i = -1;
 8     }
 9     while(i >= 65536) {
10        q = i/100;
11        r = i-((q << 6) + (q << 5) +(q << 2);
12        i=q;
13        buf [--charPos] = DigitOnes[r];
14        buf [--charPos] = DigitTens[r];
15     }
16 

继续临摹,话说代码到这边我还是可以接受的,每次取头两位数转换成char放进buf数组。但是我看到后面的一段我简直要崩溃了。。这是何等的卧槽,为什么能把代码写得这么优雅。。。

//Fall thru to fast mode for smaler numbers
//assert(i <=65536, i);
for(; ;) {
    q = (i *52429)>>> (16+3);
    r = i - (( q << 3) + (q << 1));//r = i-(q*10);
    buf[--charPos] = digits [r];
    i = q;
    if (i == 0)break;
}
    if(sign != 0) {
       buf [--charPos] = sign;
    }
}

 简直帅炸了好不好,终于知道为什么前面要用65536分界了。因为65536*52429会越界。q = (i*52429)>>>(16+3)相当于i*52429/524288。52429/524288=0.1000004.这真他妈是把程序的速度提升到了极致。写代码居然是一件这么有趣的事。捂脸.jpg。

1 public static String toString(int i) {
2    if (i == Integer.MIN_VALUE)
3         return "-2147483648";
4    int size = (i<0)? stringSize(-i) + 1 : stringSize(i);
5    char[] buf = new char[size];
6    getChars(i, size ,buf);
7    return new String(buf, true);
8 }

 toString本身倒是很好理解,第一个if主要是因为int负数的范围比正数大一,不当特例列出来,判断数组位数会有困难。下面一句负数的时候位数加一是因为负数有符号-。

讲道理今天还看了一个parseInt的实现,主要通过调用Character.digit().要写作业了,懒得写了。未完待续,慢慢补完全部。。。

以上是关于java--学习Integer源码(慢慢补)的主要内容,如果未能解决你的问题,请参考以下文章

Java源码——Integer

Java 源码学习系列——Integer

为啥我的Intellij Idea的代码补全中没有object

15Java常用类(数组工具类Arrays)基本类型包装类(Integer类)正则表达式String的split(String regex)和replaceAll(String regex, (代码片

2020 Java 面试题 小结 (答案慢慢补上,有错误请指出)

JAVA——底层源码阅读——包装数据类型Integer.valueOf()自动装箱方法底层源码分析