Javaソース読書ノート-integer
5385 ワード
継承されたクラスNumber、実装されたインタフェースCompareable
Compareableは比較用のインターフェース(またくだらない話)です.主にソートに使用されます.
最小値MIN_VALUEは0 x 8000000で最大値MAX_よりVALUE:0 x 7 fffffffはもう一人大きいですか?
整数はJVMでは補数として表され,先頭は正負,残りのビットは数値として表される.原コードで表すと、正零(0000......)と負零(10000......)の区別があり、int値が32ビットあると、原コードが表示できる最小値は-(2^31-1)であることが知られています.一方、符号化表現を使用すると、ゼロはその中の1つの配列しか占めず、より多くの数値が最小値を表すことができ、元の符号が表すことができる最小値は元の符号が表すよりも1つ小さい、すなわち-(2^31)=-21748483648である.MAX_VALUEはよく理解して、1位はゼロで整数を代表して、残りはすべて1で、それでは+2^31-1です;
数値回転文字列toString()に関する主な方法
toString(int i):前述したように、最小値は特殊な値で表されるので、iが最小値である場合は「-2174483648」に直接戻ります.iが負の値である場合、文字列の長さは絶対値のビット数よりも1ビット多い、すなわちシンボルビットを意味する.次にgetchars()を使用して各数字に対応する文字を取得し、最後にStringに変換して返します.
デジタル文字配列コアメソッド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を乗じて正確な値を得るが,減算が加算より速いためと推測される),すべての文字を巡回すると、結果も得られます.
decodeとparseIntの違い
parseIntは文字列(10進数)を数値に変換するために使用され、decodeは異なる進数の数値を分析することができる.
Integerバッファは効率を向上させるため、Integerは範囲[-128127]の数字をバッファリングし、Integerの値がこの間に初期化されると、バッファ内の既存のインスタンスを直接使用することができ、そうでないと新しいインスタンスが作成されます.
equals()とhashcode()の書き換え
equalsは2つのintegerが同じvalueを持っているかどうかを返すように書き換えられ、hashcodeはIntegerを返すvalueに書き換えられる.これは,2つのIntegerに含まれるvalueが等しい限り,両者が同じオブジェクトを参照しているかどうかにかかわらずequalsを用いて比較した結果はtrueに違いないことを意味する.一方、==の使用については、バッファの存在により、[-128127]間の数字であれば、いずれにしても新規オブジェクトが参照されるため、値が同じアドレスであれば==はtrueを返す.2回作成したInteger(133)のように、この範囲外の数字は異なり、アドレスは異なり、==自然にfalseに戻ります.
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に戻ります.