Arbeiten mit Integer
Als Wrapper-Klasse stellt Integer verschiedene Methoden zum Arbeiten mit int sowie eine Reihe von Methoden zum Konvertieren von int in String und String in int bereit . Die Klasse hat zwei Konstruktoren:-
public Integer(int i) , wobei i ein zu initialisierender primitiver Wert ist. Dadurch wird ein Integer- Objekt erstellt, das mit dem int- Wert initialisiert wird .
-
public Integer(String s) löst NumberFormatException aus . Hier ist s eine String-Darstellung des int- Werts. Dieser Konstruktor erstellt ein Integer- Objekt, das mit dem durch die Zeichenfolgendarstellung bereitgestellten int- Wert initialisiert wurde .
Erstellung ganzzahliger Objekte
Es gibt verschiedene Optionen zur Erstellung von Integer- Objekten. Einer der am häufigsten verwendeten ist der einfachste. Hier ist ein Beispiel:Integer myInteger = 5;
Die Initialisierung der Integer- Variablen ähnelt in diesem Fall der Initialisierung der primitiven int- Variablen. Übrigens können Sie eine Integer- Variable mit dem Wert eines int initialisieren . Hier ist ein Beispiel:
int myInt = 5;
Integer myInteger = myInt;
System.out.println(myInteger);
Die Ausgabe hier ist:
Integer myInteger = new Integer(5);
Mit der Variablen „Integer“ können Sie dasselbe tun wie mit int (addieren, subtrahieren, multiplizieren, dividieren, erhöhen, dekrementieren). Es ist jedoch wichtig zu bedenken, dass Integer ein Referenzdatentyp ist und eine Variable dieses Typs null sein kann. In diesem Fall ist es besser, von solchen Operationen abzusehen.
Integer myInteger1 = null;
Integer myInteger2 = myInteger1 + 5;
Hier erhalten wir eine Ausnahme:
Ganzzahlige Klassenkonstanten
Die Integer- Klasse stellt verschiedene Konstanten und Methoden für die Arbeit mit Ganzzahlen bereit. Hier sind sie:-
GRÖSSE bezeichnet die Anzahl der Bits im zweistelligen Zahlensystem, die vom Typ int belegt sind
-
BYTES ist die Anzahl der Bytes im zweistelligen Zahlensystem, die vom Typ int belegt werden
-
MAX_VALUE ist der maximale Wert, den der int- Typ enthalten kann
-
MIN_VALUE ist der Mindestwert, den der int- Typ enthalten kann
-
TYPE gibt ein Objekt vom Typ Class vom Typ int zurück
Die nützlichsten Methoden der Integer-Klasse
Werfen wir nun einen Blick auf die am häufigsten verwendeten Methoden der Integer- Klasse. Ich vermute, dass die beliebtesten Methoden zum Konvertieren einer Zahl aus einem String oder umgekehrt sind.-
static int parseInt(String s) Diese Methode konvertiert String in int . Wenn die Konvertierung nicht möglich ist, wird eine NumberFormatException ausgelöst.
-
static int parseInt(String s, int radix) Diese Methode konvertiert auch den s- Parameter in einen int . Der Radix- Parameter gibt an, dass das Zahlensystem s ursprünglich geschrieben wurde.
-
static Integer valueOf(int i) gibt eine Ganzzahl zurück, deren Wert i ist ;
-
static Integer valueOf(String s) funktioniert wie parseInt(String s) , aber das Ergebnis ist Integer , nicht int ;
-
static Integer valueOf(String s, int radix) funktioniert genauso wie parseInt(String s, int radix) , aber das Ergebnis ist ein Integer und kein int .
Gibt es ein Problem mit der Integer-Klasse? Oh ja, es gibt ...
Daher gibt es in Java zwei Typen für Ganzzahlen (die in 32 Bit passen): int und Integer . Um die Besonderheiten jedes einzelnen davon zu verstehen, müssen wir Folgendes über das JVM-Speichermodell wissen: Alles, was Sie deklarieren, wird entweder im Stapelspeicher (JVM-Stack spezifisch für jeden Thread) oder im Heap-Speicherplatz gespeichert. Primitive Typen ( int , long , float , boolean , double , char , byte usw.) werden im Stapelspeicher gespeichert. Alle Objekte und Arrays werden im Heap-Bereich gespeichert. Referenzen auf diese Objekte und Arrays, die für die Methoden benötigt werden, werden im Stack gespeichert. Also. Warum kümmert es uns? Nun, Stack ist kleiner als Heap (ein Nachteil), aber es ist viel schneller, Werte im Stack zuzuweisen als im Heap (ein Vorteil). Beginnen wir mit einem primitiven Typ int . Es nimmt genau 32 Bit ein. Das sind 32/8=4 Bytes. Weil es ein primitiver Typ ist. Betrachten wir nun Integer . Es ist ein Objekt mit zusätzlichem Overhead und Ausrichtungen. Ich habe ein Bibliotheksjol verwendet, um seine Größe zu messen:public static void main(String[] args) {
System.out.println(ClassLayout.parseInstance(Integer.valueOf(1)).toPrintable());
}
und es stellte sich heraus, dass es 16 Bytes beanspruchte:
public static void main(String[] args) {
int[] array = new int[1000];
for (int i = 0; i < 1000; i++) array[i] = i; System.out.println(ClassLayout.parseInstance(array).toPrintable());
}
Und das Ergebnis sind 4016 Bytes:
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) list.add(i);
System.out.println(GraphLayout.parseInstance(list).toFootprint());
}
Und das Ergebnis sind 20040 Bytes (nochmals viermal mehr!):
public static void main(String[] args) {
TIntList list = new TIntArrayList(1000);
for (int i = 0; i < 1000; i++) list.add(i);
System.out.println(GraphLayout.parseInstance(list).toFootprint());
}
Und das Ergebnis sind 4040 Bytes (fast das Gleiche wie nur int[] !):
benchmark {
configurations {
main {
warmups = 5 // number of warmup iterations
iterations = 50 // number of iterations
iterationTime = 500 // time in seconds per iteration
iterationTimeUnit = "ns" // time unit for iterationTime
Die Benchmarks:
private static final Random random = new Random();
@Benchmark
public int testPrimitiveIntegersSum() {
int a = random.nextInt();
int b = random.nextInt();
return a + b;
}
@Benchmark
public Integer testBoxedIntegersSum() {
Integer a = random.nextInt();
Integer b = random.nextInt();
return a + b;
}
Die Ergebnisse:
@Benchmark
public int testPrimitiveArray() {
int[] array = new int[1000];
for (int i = 0; i < 1000; i++) array[i] = i;
int sum = 0;
for (int x : array) sum += x;
return sum;
}
11933.545 ops/s [Average]
@Benchmark
public int testBoxesArray() {
Integer[] array = new Integer[1000];
for (int i = 0; i < 1000; i++) array[i] = i;
int sum = 0;
for (int x : array) sum += x;
return sum;
}
2733.312 ops/s [Average]
@Benchmark
public int testList() {
List<Integer> list = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) list.add(i);
int sum = 0;
for (int x : list) sum += x;
return sum;
}
2086.379 ops/s [Average]
@Benchmark
public int testTroveIntList() {
TIntList list = new TIntArrayList(1000);
for (int i = 0; i < 1000; i++) list.add(i);
int sum = 0;
for (int i = 0; i < 1000; i++) sum += list.get(i);
return sum;
}
5727.979 ops/s [Average]
Die Ergebnisse: Das Primitiv-Array ist mehr als viermal schneller als das Array mit geschachtelten Werten ( Integer ). fast sechsmal schneller als ArrayList von geschachtelten Werten ( Integer s); und doppelt so schnell wie eine TIntArrayList (die tatsächlich ein Array primitiver Ints dekoriert). Wenn Sie also eine Datenstruktur benötigen, um eine Sammlung ganzzahliger Werte zu speichern, und sich deren Größe nicht ändern soll, verwenden Sie ein int[] ; Wenn sich die Größe ändern soll, möchten Sie möglicherweise die tove4j-Bibliothek mit TIntArrayList verwenden . Und hier kommt das Ende meines Aufsatzes, in dem ich die Nachteile der Verwendung des Integer- Typs erläutere. Es gibt einige interessante statische Methoden von Integer , über die ich sprechen sollte, bevor ich fertig bin. public static Integer getInteger(String nm, int val) macht nicht das, was man denken könnte, sondern ruft einen Integer- Wert einer Systemeigenschaft ab. Val ist der Standardwert, falls diese Eigenschaft nicht festgelegt ist. public static String toBinaryString(int i) gibt einen String mit einer binären Darstellung einer Zahl zurück. Es gibt Methoden zum Abrufen einer 16-basierten ( toHexString ) und 8-basierten ( toOctalString ) Darstellung. Es gibt eine Methode, um einen String in einen int zu analysieren . Auch wenn es sich bei der Zeichenfolge um eine nicht auf 10 Basiswerten basierende Darstellung handelt. Hier sind einige Beispiele: Integer.parseInt("-FF", 16) gibt -255 zurück. Integer.parseInt("+42", 10) gibt 42 zurück . Integer.parseInt("1100110", 2) gibt 102 zurück
GO TO FULL VERSION