JAVA学习随笔(2)--Integer类

来源:互联网 发布:雷科防务怎么样 知乎 编辑:程序博客网 时间:2024/05/17 22:54
public final class Integer extends Number implements Comparable<Integer>

public final 类,继承关系.
属性:

   /**     * A constant holding the minimum value an {@code int} can     * have, -2<sup>31</sup>.     */    @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   MAX_VALUE = 0x7fffffff;    /**     * The {@code Class} instance representing the primitive type     * {@code int}.     *     * @since   JDK1.1     */    @SuppressWarnings("unchecked")    public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");    /**     * All possible chars for representing a number as a String     */    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'    };

toUnsignedString方法,根据进制int转对应字符串,转换代码分析在学习随笔(1)中学习了。

public static String toUnsignedString(int i, int radix) {        return Long.toUnsignedString(toUnsignedLong(i), radix);    }
public static String toHexString(int i) {        return toUnsignedString0(i, 4);    }
public static String toOctalString(int i) {        return toUnsignedString0(i, 3);    }
public static String toBinaryString(int i) {        return toUnsignedString0(i, 1);    }

全是static方法,类直接调用。
这个方法在学习随笔(1) 中学习了,不细说了

    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 - 1)) / shift), 1);        char[] buf = new char[chars];        formatUnsignedInt(val, shift, buf, 0, chars);        // Use special constructor which takes over "buf".        return new String(buf, true);    }

int转字符串

    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);    }

临界值判断,申请缓存,getChars方法为具体逻辑函数:

    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 - ((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;        }    }

先看这段函数

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

实质是每次取i的最后两位数存在r中,然后i/100,q = i/100,然后(q << 6) + (q << 5) + (q << 2)就等于q*100,再r = i - q*100,r就是最后两位数,然后直接索引对应的个位和十位数组,从后到前存在buf数组中:

    final static char [] DigitTens = {        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',        } ;    final static char [] DigitOnes = {        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',        } ;

当i小于等于65536时,用更快的转换方法:

        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;        }

他这个做法和上面的差不多,r为每次取的数字的最后一位,因为2的19次方为524288,比较下52429这个数字,就不难明白了。而且(q << 3) + (q << 1)就是q*10,和上面的一样吧。

再看看计算int位数的函数:

    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;    }

明显的空间换时间啊,时间复杂度o(n).

再看看字符串转int函数:

    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 = 0;        boolean negative = false;        int i = 0, len = s.length();        int limit = -Integer.MAX_VALUE;        int multmin;        int digit;        if (len > 0) {            char firstChar = s.charAt(0);            if (firstChar < '0') { // Possible leading "+" or "-"                if (firstChar == '-') {                    negative = true;                    limit = Integer.MIN_VALUE;                } else if (firstChar != '+')                    throw NumberFormatException.forInputString(s);                if (len == 1) // 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 < 0) {                    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;    }

首先,这个判断第一个char符号位正负性和合法性的代码很灵性啊:

            if (firstChar < '0') { // Possible leading "+" or "-"                if (firstChar == '-') {                    negative = true;                    limit = Integer.MIN_VALUE;                } else if (firstChar != '+')                    throw NumberFormatException.forInputString(s);                if (len == 1) // Cannot have lone "+" or "-"                    throw NumberFormatException.forInputString(s);                i++;            }

首先if (firstChar < ‘0’),因为+和-号的ascII码都小于’0’,这样就直接判断是非数字字符了。multmin为转换后的数字的下界,然后依次取每位字符转换为int,然后保存在result里。注意他默认保存的是负数,所以最后的返回值为return negative ? result : -result;

对应字符串转10进制数字函数:

 public static int parseInt(String s) throws NumberFormatException {        return parseInt(s,10);    }

先看到这,留点明天接着看~

0 0