Travailler avec un nombre entier
En tant que classe wrapper, Integer fournit diverses méthodes pour travailler avec int , ainsi qu'un certain nombre de méthodes pour convertir int en String et String en int . La classe a deux constructeurs :-
public Integer(int i) , où i est une valeur primitive à initialiser. Celui-ci crée un objet Integer initialisé avec la valeur int .
-
public Integer(String s) lance NumberFormatException . Ici , s est une représentation sous forme de chaîne de la valeur int . Ce constructeur crée un objet Integer qui a été initialisé avec la valeur int fournie par la représentation sous forme de chaîne .
Création d'objet entier
Il existe différentes options de création d'objets Integer . L’un des plus couramment utilisés est le plus simple. Voici un exemple:
Integer myInteger = 5;
L'initialisation de la variable Integer dans ce cas est similaire à l'initialisation de la variable int primitive . À propos, vous pouvez initialiser une variable Integer avec la valeur d'un int . Voici un exemple:
int myInt = 5;
Integer myInteger = myInt;
System.out.println(myInteger);
Le résultat ici est :
Integer myInteger = new Integer(5);
Vous pouvez faire avec la variable Integer la même chose qu'avec int (ajouter, soustraire, multiplier, diviser, incrémenter, décrémenter). Cependant, il est important de se rappeler qu’Integer est un type de données de référence et qu’une variable de ce type peut être nulle. Dans ce cas, il vaut mieux s'abstenir de telles opérations.
Integer myInteger1 = null;
Integer myInteger2 = myInteger1 + 5;
Ici, nous aurons une exception :
Constantes de classe entière
La classe Integer fournit diverses constantes et méthodes pour travailler avec des entiers. Les voici:-
SIZE signifie le nombre de bits dans le système numérique à deux chiffres occupés par le type int
-
BYTES est le nombre d'octets dans un système numérique à deux chiffres occupés par le type int
-
MAX_VALUE est la valeur maximale que le type int peut contenir
-
MIN_VALUE est la valeur minimale que le type int peut contenir
-
TYPE renvoie un objet de type Class de type int
Méthodes les plus utiles de la classe entière
Jetons maintenant un aperçu des méthodes les plus utilisées de la classe Integer . Les plus populaires d'entre elles, je suppose, sont les méthodes permettant de convertir un nombre à partir d'un String , ou vice versa.-
static int parseInt(String s) cette méthode convertit String en int . Si la conversion n'est pas possible, NumberFormatException sera levée.
-
static int parseInt(String s, int radix) cette méthode convertit également le paramètre s en int . Le paramètre radix indique que le système numérique s a été initialement écrit.
-
static Integer valueOf(int i) renvoie un Integer dont la valeur est i ;
-
static Integer valueOf(String s) fonctionne comme parseInt(String s) , mais le résultat sera Integer , pas int ;
-
static Integer valueOf(String s, int radix) fonctionne de la même manière que parseInt(String s, int radix) , mais le résultat est un Integer , pas un int .
Y a-t-il un problème avec la classe Integer ? Ah ouais, il y a…
Il existe donc deux types d'entiers (qui tiennent dans 32 bits) en Java : int et Integer . Pour comprendre les spécificités de chacun d'eux, nous devons connaître les éléments suivants sur le modèle de mémoire JVM : tout ce que vous déclarez est stocké soit dans la mémoire de pile (pile JVM spécifique à chaque thread), soit dans l'espace de tas. Les types primitifs ( int , long , float , boolean , double , char , byte , etc.) sont stockés dans la mémoire Stack. Tous les objets et tableaux sont stockés dans l'espace tas. Les références à ces objets et tableaux nécessaires aux méthodes sont stockées dans Stack. Donc. Pourquoi nous en soucions-nous ? Eh bien, vous voyez, Stack est plus petit que Heap (un inconvénient), mais il est beaucoup plus rapide d'allouer des valeurs dans Stack que dans Heap (un pro). Commençons par un type primitif int . Cela prend exactement 32 bits. C'est 32/8 = 4 octets. Parce que c'est un type primitif. Considérons maintenant Integer . C'est un objet, avec des frais généraux et des alignements supplémentaires. J'ai utilisé une bibliothèque jol pour mesurer sa taille :
public static void main(String[] args) {
System.out.println(ClassLayout.parseInstance(Integer.valueOf(1)).toPrintable());
}
et il s'est avéré qu'il occupait 16 octets :
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());
}
Et le résultat est de 4016 octets :
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());
}
Et le résultat est de 20040 octets (encore une fois, 4 fois plus !) :
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());
}
Et le résultat est de 4040 octets (presque le même que simplement 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
Les repères :
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;
}
Les résultats:
@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]
Les résultats : le tableau de primitives est plus de 4 fois plus rapide que le tableau de valeurs encadrées ( Integer s) ; presque six fois plus rapide que ArrayList de valeurs encadrées ( Integer s); et deux fois plus rapide qu'un TIntArrayList (qui décore en fait un tableau d'entiers primitifs). Par conséquent, si vous avez besoin d’une structure de données pour stocker une collection de valeurs entières et que sa taille ne va pas changer, utilisez un int[] ; si la taille doit changer, vous souhaiterez peut-être utiliser la bibliothèque tove4j avec TIntArrayList . Et voici la fin de mon essai où j'explique les inconvénients de l'utilisation du type Integer . Il existe des méthodes statiques intéressantes de Integer , dont je devrais parler avant de terminer. public static Integer getInteger(String nm, int val) ne fait pas ce que l'on pourrait penser, mais récupère une valeur Integer d'une propriété système. Val est la valeur par défaut au cas où cette propriété ne serait pas définie. public static String toBinaryString(int i) renvoie une chaîne avec une représentation binaire d'un nombre. Il existe des méthodes pour récupérer des représentations basées sur 16 ( toHexString ) et basées sur 8 ( toOctalString ). Il existe une méthode pour analyser une String en un int . Même si la chaîne est une représentation basée sur une base autre que 10. Voici quelques exemples : Integer.parseInt("-FF", 16) renvoie -255 Integer.parseInt("+42", 10) renvoie 42 Integer.parseInt("1100110", 2) renvoie 102
GO TO FULL VERSION