javadata structure and algorithms

java Integer 源码分析

2019-10-27  本文已影响0人  spraysss

Intergerint的包装类型,实现了Number接口,具有可比较可序列化特性:

public final class Integer extends Number implements Comparable<Integer> 
Integer

Integer可以表示的范围

Integer 可以表示- 2^{31}2^{31}-1之间的整数即: -2147483648 ~2147483647

在Integer中定义了两个常量MIN_VALUEMIN_VALUE分别代表其最小值和最大值


    @Native public static final int   MIN_VALUE = 0x80000000;

    /**
     * A constant holding the maximum value an {@code int} can
     * have, 2<sup>31</sup>-1.
     */
    @Native public static final int   MIN_VALUE = 0x7fffffff;

toString()方法

不带参数的toString方法用于将Integer对象转化为十进制字符串

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

stringSize方法用于计算Integer对象是一个几位数,小于等于9是个位数,小于等于99是十位数,Integer可以表示的最大数是10位数

   final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, Integer.MAX_VALUE };

    // Requires positive x
    static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
    }
 static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        if (i < 0) {
            sign = '-';
            i = -i;
        }

        // Generate two digits per iteration
        while (i >= 65536) {
            q = i / 100;
            // really: r = i - (q * 100);
            //相当于  r=i%100
            r = i - ((q << 6) + (q << 5) + (q << 2));
            i = q;
            buf [--charPos] = DigitOnes[r];
            buf [--charPos] = DigitTens[r];
        }

        // Fall thru to fast mode for smaller 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;
        }
    }

getChars方法是toString的关键:

  1. 第一个while循环的流程是当i> 65536时,每次将其除以100,并且获得除以100的余数,这样的话就相当于从右向左处理,每次处理两位。
    r = i - ((q << 6) + (q << 5) + (q << 2))这个就等价与r=i%100, 为什么呢,因为100=2^6+2^5+2^2 ,所以:
r = i - ((q << 6) + (q << 5) + (q << 2))  等价于:
r = i - (q * 100) 等价于:
r= i % 100

这里使用位运算提高操作效率

  1. for循环里面q = (i * 52429) >>> (16+3); r = i - ((q << 3) + (q << 1));这两步看起来花里胡哨的,实际上是在做q = i / 10; r= i % 10 ;, 这样的话就相当于从右向左处理,每次处理一位。因为:
(i * 52429) >>> (16+3)
= (i * 52429) / 2的19次方
= (i * 52429) / 524288
= i * (52429 / 524288)
= i * 0.1000003814697266
= i * 0.1
= i / 10

参考

https://blog.csdn.net/lianjiww/article/details/82715250

上一篇下一篇

猜你喜欢

热点阅读