Irgendwie habe ich beschlossen, auch die JDK-Quelle zu lesen. Trotzdem habe ich keine Zeit, jede Zeile sorgfältig zu lesen, also habe ich sie kurz gelesen und diesen Code gefunden. Da das letzte Mal ich habe die Quelle von Short gelesen war, wird das nächste Integer sein.
Die Integer-Klasse ist eine Wrapper-Klasse für den primitiven Typ int. Erstens Felder und Konstruktoren. Nun, es ist eine Quelle, die sich jeder vorstellen kann.
Integer.java
private final int value;
public Integer(int value) {
this.value = value;
}
Tatsächlich gibt es eine IntegerCache-Klasse, die in Javadoc nicht angezeigt wird.
Integer.java
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
Byte, Short kam und zog sich um. Da diese innere Klasse privat ist, können Sie normalerweise nicht lesen, was im Javadoc-Kommentar geschrieben steht. Es scheint, dass Sie die Obergrenze von 127 mit der Startoption -XX: AutoBoxCacheMax = size erhöhen können. Laut Numeric Cache wurde es aus JDK 1.6 hinzugefügt.
Lassen Sie uns die Quelle von JDK 1.5 überprüfen.
Integer.java
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
Oh, es ist erfrischend. Wie Byte und Short war es von -128 bis 127. Obwohl es sich um IntegerCache handelt, wird es von valueOf wie Byte und Short referenziert.
Integer.java
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
Vergleichen Sie wie bei Short die Instanzen mit 127 und 128.
Main.java
public static void main(String[] args) {
int i00 = 127;
Integer i01 = Integer.valueOf(i00);
Integer i02 = i00;
System.out.println(i01 == i02);
int i10 = 128;
Integer i11 = Integer.valueOf(i10);
Integer i12 = i10;
System.out.println(i11 == i12);
}
Wenn du rennst ...
$ java Main
true
false
$ java -XX:AutoBoxCacheMax=127 Main
true
false
$ java -XX:AutoBoxCacheMax=128 Main
true
true
Startoption -XX: AutoBoxCacheMax funktioniert.
In dem ins Japanische übersetzten Javadoc heißt es: "Hinweise zur Implementierung: Die Implementierung der" Bit Twiddling "-Methode (höchstes OneBit und numberOfTrailingZeros) ist" Hacker's Delight "(Addison Wesley, 2002) von Henry S. Warren, Jr. ) Es basiert auf. "ist was es liest. Da es aus JDK 1.5 stammt, wissen es wahrscheinlich viele von Ihnen, aber lassen Sie uns die Quelle nach der "HD" -String durchsuchen.
Integer.java
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
public static int lowestOneBit(int i) {
// HD, Section 2-1
return i & -i;
}
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
public static int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - ((i << 1) >>> 31);
}
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
public static int signum(int i) {
// HD, Section 2-7
return (i >> 31) | (-i >>> 31);
}
bitCount fühlt sich ein wenig an, wenn Sie sich [Algorithmus zum Zählen / Suchen von Bits] ansehen (http://www.nminoru.jp/~nminoru/programming/bitcount.html). Es scheint viel schneller zu sein, als selbst zu schleifen und zu zählen. Wann benutzt du das Problem ... highOneBit löste das Problem und ich hatte die Möglichkeit, es zu nutzen. → Weihnachtswettbewerb 2016 / A --Array Sum
Es gibt ziemlich viele, also habe ich nur drei aufgenommen.
Integer.java
public static int sum(int a, int b) {
return a + b;
}
public static int max(int a, int b) {
return Math.max(a, b);
}
public static int min(int a, int b) {
return Math.min(a, b);
}
Ich brauche es nicht wirklich. Wenn Sie es trotzdem machen wollen, sollten Sie eine int-Version von Math.pow () machen. (1/13 Nachschrift) Nun, wenn es sich um eine Summe handelt, wenn es sich um eine Methode handelt, die beispielsweise das Überspringen einer Ausnahme beim Überlaufen entwickelt hat, ist sie immer noch wertvoll, aber was ist mit einer Methode, die nur a + b zurückgibt? Und da es sich um eine Integer-Klasse handelt, kommen nicht statische Methoden wie Integer add (Integer other) gut zur Geltung ... (1/13 postscript) @see java.util.function.BinaryOperator ist im javadoc-Kommentar geschrieben, aber hat es Sinn gemacht?
(1/13 Nachschrift) Ich habe es leicht übersprungen, aber ich habe es hinzugefügt, indem ich Long.parseUnsignedLong angesehen habe.
Ab JDK 1.8 wurde parseUnsignedInt hinzugefügt. Ist Java Int nicht signiert? Was bedeutet es, es ohne Vorzeichen zu analysieren?
Integer.java
public static int parseUnsignedInt(String s, int radix)
throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
}
int len = s.length();
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar == '-') {
throw new
NumberFormatException(String.format("Illegal leading minus sign " +
"on unsigned string %s.", s));
} else {
if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
(radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
return parseInt(s, radix);
} else {
long ell = Long.parseLong(s, radix);
if ((ell & 0xffff_ffff_0000_0000L) == 0) {
return (int) ell;
} else {
throw new
NumberFormatException(String.format("String value %s exceeds " +
"range of unsigned int.", s));
}
}
}
} else {
throw NumberFormatException.forInputString(s);
}
}
Ich fragte mich, ob ich 0xffff_ffff_0000_0000L schreiben könnte, aber wenn es nur ein Wert von weniger als 32 Bit wäre, würde ich ihn mit int umwandeln. Mit anderen Worten, selbst wenn das Codebit gesetzt ist, wird es als int umgewandelt, so dass es negativ ist. Es analysiert unsigniert, kann aber negativ sein. Es ist eine großartige Spezifikation.
Lass es uns versuchen.
Main.java
public static void main(String[] args) {
int i01 = Integer.parseUnsignedInt("2147483647");
System.out.println(i01);
int i02 = Integer.parseUnsignedInt("2147483648");
System.out.println(i02);
int i03 = Integer.parseUnsignedInt("4294967295");
System.out.println(i03);
int i04 = Integer.parseUnsignedInt("4294967296");
System.out.println(i04);
}
Wenn du rennst ...
2147483647
-2147483648
-1
Exception in thread "main" java.lang.NumberFormatException: String value 4294967296 exceeds range of unsigned int.
at java.lang.Integer.parseUnsignedInt(Integer.java:684)
at java.lang.Integer.parseUnsignedInt(Integer.java:711)
at Main.main(Main.java:9)
Das Ergebnis ist wie erwartet, aber sind Sie glücklich? Dies. Wenn Sie 32 Bit voll verwenden möchten, können Sie long verwenden.
Die in JDK 1.8 hinzugefügten Methoden enthalten parseUnsignedInt, aber ich glaube, dass es viele statische Methoden gibt. (1/13 Nachschrift) In JDK 1.8 gab es 37 öffentliche statische Methoden. Ich denke, es wäre besser, es in die IntegerUtil-Klasse zu unterteilen, wenn es so etwas gibt. Übrigens war es 13 in JDK 1.4. Es war einmal, ich dachte, es wäre eine einfachere Klasse.
Plötzlich bemerkte ich, dass die Breite der harten Lasche 4 Zeichen betragen soll. Es war einmal, dass die Breite der harten Lasche 8 Zeichen betrug, 1 Einzug 4 Leerzeichen, 2 Einrückungen 1 harte Lasche, 3 Einrückungen 1 harte Lasche + 4 Leerzeichen und 4 Einrückungen 2 harte Laschen waren.
Vergleich der alten Quellen, --JDK 1.4 Sun Microsystems Hard Tab 8 Zeichen --JDK 1.5 Sun Microsystems Hard Tab 8 Zeichen
(1/13 Nachschrift) Ich grep es, also füge es ein public static String toString(int i, int radix) { public static String toUnsignedString(int i, int radix) { public static String toHexString(int i) { public static String toOctalString(int i) { public static String toBinaryString(int i) { public static String toString(int i) { public static String toUnsignedString(int i) { public static int parseInt(String s, int radix) public static int parseInt(String s) throws NumberFormatException { public static int parseUnsignedInt(String s, int radix) public static int parseUnsignedInt(String s) throws NumberFormatException { public static Integer valueOf(String s, int radix) throws NumberFormatException { public static Integer valueOf(String s) throws NumberFormatException { public static Integer valueOf(int i) { public static int hashCode(int value) { public static Integer getInteger(String nm) { public static Integer getInteger(String nm, int val) { public static Integer getInteger(String nm, Integer val) { public static Integer decode(String nm) throws NumberFormatException { public static int compare(int x, int y) { public static int compareUnsigned(int x, int y) { public static long toUnsignedLong(int x) { public static int divideUnsigned(int dividend, int divisor) { public static int remainderUnsigned(int dividend, int divisor) { public static int highestOneBit(int i) { public static int lowestOneBit(int i) { public static int numberOfLeadingZeros(int i) { public static int numberOfTrailingZeros(int i) { public static int bitCount(int i) { public static int rotateLeft(int i, int distance) { public static int rotateRight(int i, int distance) { public static int reverse(int i) { public static int signum(int i) { public static int reverseBytes(int i) { public static int sum(int a, int b) { public static int max(int a, int b) { public static int min(int a, int b) {
(1/13 Nachschrift) Ich grep es, also füge es ein public static String toString(int i, int radix) { public static String toHexString(int i) { public static String toOctalString(int i) { public static String toBinaryString(int i) { public static String toString(int i) { public static int parseInt(String s, int radix) public static int parseInt(String s) throws NumberFormatException { public static Integer valueOf(String s, int radix) throws NumberFormatException { public static Integer valueOf(String s) throws NumberFormatException public static Integer getInteger(String nm) { public static Integer getInteger(String nm, int val) { public static Integer getInteger(String nm, Integer val) { public static Integer decode(String nm) throws NumberFormatException {
Recommended Posts