Javaソース読書ノート-integer

5385 ワード

継承されたクラスNumber、実装されたインタフェースCompareable
public final class Integer extends Number implements Comparable
Numberは、数字(くだらない話)を表す抽象クラスです.このクラスを継承するにはintValue,doubleValueなどの抽象的な方法が必要であり,int回転doubleのような様々なタイプの数値相互変換を実現するにはdoubleValueを{return(double)value;}に実現する必要がある.
Compareableは比較用のインターフェース(またくだらない話)です.主にソートに使用されます.
最小値MIN_VALUEは0 x 8000000で最大値MAX_よりVALUE:0 x 7 fffffffはもう一人大きいですか?
@Native public static final int   MIN_VALUE = 0x80000000;
@Native public static final int   MAX_VALUE = 0x7fffffff;
まずこの2つの16進数をバイナリに変換してみます:MIN:10000000......MAX:01111111.......
整数はJVMでは補数として表され,先頭は正負,残りのビットは数値として表される.原コードで表すと、正零(0000......)と負零(10000......)の区別があり、int値が32ビットあると、原コードが表示できる最小値は-(2^31-1)であることが知られています.一方、符号化表現を使用すると、ゼロはその中の1つの配列しか占めず、より多くの数値が最小値を表すことができ、元の符号が表すことができる最小値は元の符号が表すよりも1つ小さい、すなわち-(2^31)=-21748483648である.MAX_VALUEはよく理解して、1位はゼロで整数を代表して、残りはすべて1で、それでは+2^31-1です;
数値回転文字列toString()に関する主な方法
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);
    }

toString(int i):前述したように、最小値は特殊な値で表されるので、iが最小値である場合は「-2174483648」に直接戻ります.iが負の値である場合、文字列の長さは絶対値のビット数よりも1ビット多い、すなわちシンボルビットを意味する.次にgetchars()を使用して各数字に対応する文字を取得し、最後にStringに変換して返します.
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;
        }
    }

デジタル文字配列コアメソッドgetChars(int i,int index,char[]buf);iはデータソース、indexは結果長、bufは結果を格納するための変数である.最初に負数を処理し、負数に対して記号ビットをメモして逆を取ります.そして次の逐位解析は予想と違って、私に書かせてもらうと、必ず右から左へ逐位%10を取って、対応する文字に変換します.しかし、ここでの処理がより複雑であることは明らかであるが、乗算再減算を用いて2つの数字単位で解析(>>n演算子は左に移動して0を充填することを示し、すなわち2^nを乗算することであり、ここでの(q<<6)+(q<<5)+(q<<2)は実際にはq*100である)は、乗算の速度が除算よりはるかに大きいためである.本当に大神の手書きだと言わざるを得ない.
文字列回転数parseInt(String s,int radix)に関する主な方法
TOStringに比べて簡単ですが、radixは進数を表し、sは変換する文字列を表します.まずトップに出現する可能性のある「+」,「-」を判断し,次いでビット毎に左から右へデジタルdigit(abcdefなどの16進数への変換を含む)に変換し,resultに進数を乗じた後にdigitを減算する(加算ではなく,つまりResultは計算すればするほど小さくなり,最後に−1を乗じて正確な値を得るが,減算が加算より速いためと推測される),すべての文字を巡回すると、結果も得られます.
public static int parseInt(String s, int radix)
                throws NumberFormatException
    {
        /*      */
        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);
                /*      */
                result *= radix;
                
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        return negative ? result : -result;
    }

   
decodeとparseIntの違い
parseIntは文字列(10進数)を数値に変換するために使用され、decodeは異なる進数の数値を分析することができる.
Integerバッファは効率を向上させるため、Integerは範囲[-128127]の数字をバッファリングし、Integerの値がこの間に初期化されると、バッファ内の既存のインスタンスを直接使用することができ、そうでないと新しいインスタンスが作成されます. 
equals()とhashcode()の書き換え
public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
public int hashCode() {
        return Integer.hashCode(value);
    }

equalsは2つのintegerが同じvalueを持っているかどうかを返すように書き換えられ、hashcodeはIntegerを返すvalueに書き換えられる.これは,2つのIntegerに含まれるvalueが等しい限り,両者が同じオブジェクトを参照しているかどうかにかかわらずequalsを用いて比較した結果はtrueに違いないことを意味する.一方、==の使用については、バッファの存在により、[-128127]間の数字であれば、いずれにしても新規オブジェクトが参照されるため、値が同じアドレスであれば==はtrueを返す.2回作成したInteger(133)のように、この範囲外の数字は異なり、アドレスは異なり、==自然にfalseに戻ります.