Trabalhando com inteiro
Como uma classe wrapper, Integer fornece vários métodos para trabalhar com int , bem como vários métodos para converter int em String e String em int . A classe possui dois construtores:-
public Integer(int i) , onde i é um valor primitivo para inicializar. Este cria um objeto Integer que é inicializado com o valor int .
-
public Integer(String s) lança NumberFormatException . Aqui s é uma representação em string do valor int . Este construtor cria um objeto Integer que foi inicializado com o valor int fornecido pela representação de string .
Criação de objeto inteiro
Existem diferentes opções de criação de objetos inteiros . Um dos mais comumente usados é o mais fácil. Aqui está um exemplo:Integer myInteger = 5;
A inicialização da variável Integer neste caso é semelhante à inicialização da variável int primitiva . A propósito, você pode inicializar uma variável Integer com o valor de um int . Aqui está um exemplo:
int myInt = 5;
Integer myInteger = myInt;
System.out.println(myInteger);
A saída aqui é:
Integer myInteger = new Integer(5);
Você pode fazer com a variável Integer o mesmo que com int (adicionar, subtrair, multiplicar, dividir, incrementar, decrementar). Porém, é importante lembrar que Inteiro é um tipo de dados de referência e uma variável desse tipo pode ser nula. Neste caso, é melhor abster-se de tais operações.
Integer myInteger1 = null;
Integer myInteger2 = myInteger1 + 5;
Aqui teremos uma exceção:
Constantes de classe inteira
A classe Integer fornece várias constantes e métodos para trabalhar com números inteiros. Aqui estão eles:-
SIZE significa o número de bits no sistema numérico de dois dígitos ocupados pelo tipo int
-
BYTES é o número de bytes no sistema numérico de dois dígitos ocupados pelo tipo int
-
MAX_VALUE é o valor máximo que o tipo int pode conter
-
MIN_VALUE é o valor mínimo que o tipo int pode conter
-
TYPE retorna um objeto do tipo Class do tipo int
Métodos mais úteis da classe inteira
Agora vamos dar uma olhada nos métodos mais usados da classe Integer . O mais popular deles, presumo, são métodos para converter um número de String , ou vice-versa.-
static int parseInt(String s) este método converte String em int . Se a conversão não for possível, NumberFormatException será lançada.
-
static int parseInt(String s, int radix) este método também converte o parâmetro s em um int . O parâmetro radix indica que o sistema numérico foi originalmente escrito.
-
static Integer valueOf(int i) retorna um inteiro cujo valor é i ;
-
static Integer valueOf(String s) funciona como parseInt(String s) , mas o resultado será Integer , não int ;
-
static Integer valueOf(String s, int radix) funciona da mesma forma que parseInt(String s, int radix) , mas o resultado é um Integer , não um int .
Existe algum problema com a classe Integer? Ah sim, existe…
Portanto, existem dois tipos de números inteiros (que cabem em 32 bits) em Java: int e Integer . Para entender as especificidades de cada um deles precisamos saber o seguinte sobre o modelo de memória JVM: tudo que você declara é armazenado ou em Stack Memory (JVM Stack específico para cada Thread), ou Heap Space. Tipos primitivos ( int , long , float , boolean , double , char , byte , etc) são armazenados na memória Stack. Todos os objetos e arrays são armazenados no Heap Space. As referências a esses objetos e arrays necessários para os métodos são armazenadas em Stack. Então. Por que nos importamos? Bem, veja bem, Stack é menor que Heap (um contra), mas é muito mais rápido alocar valores em Stack do que em Heap (um profissional). Vamos começar com um tipo primitivo int . Ocupa exatamente 32 bits. Isso é 32/8 = 4 bytes. Porque é um tipo primitivo. Agora, vamos considerar Integer . É um objeto, com sobrecarga e alinhamentos extras. Eu usei uma biblioteca jol para medir seu tamanho:public static void main(String[] args) {
System.out.println(ClassLayout.parseInstance(Integer.valueOf(1)).toPrintable());
}
e acabou ocupando 16 bytes:
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());
}
E o resultado são 4.016 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());
}
E o resultado são 2.0040 bytes (novamente, 4 vezes mais!):
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());
}
E o resultado é 4.040 bytes (quase o mesmo que apenas 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
Os 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;
}
Os resultados:
@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]
Os resultados: o array de primitivos é mais de 4 vezes mais rápido que o array de valores em caixa ( Integer s); quase seis vezes mais rápido que ArrayList de valores em caixa ( Integer s); e duas vezes mais rápido que um TIntArrayList (que na verdade decora uma matriz de entradas primitivas). Portanto, se você precisa de uma estrutura de dados para armazenar uma coleção de valores inteiros e seu tamanho não vai mudar, use um int[] ; se o tamanho for mudar - você pode querer usar a biblioteca tove4j com TIntArrayList . E aqui chega o final do meu ensaio, onde explico os contras de usar o tipo Integer . Existem alguns métodos estáticos interessantes de Integer , sobre os quais devo falar antes de terminar. public static Integer getInteger(String nm, int val) não faz o que se poderia pensar, mas recupera um valor inteiro de uma propriedade do sistema. Val é o padrão caso esta propriedade não esteja definida. public static String toBinaryString(int i) retorna uma String com uma representação binária de um número. Existem métodos para recuperação de representações baseadas em 16 ( toHexString ) e baseadas em 8 ( toOctalString ). Existe um método para analisar uma String em um int . Mesmo que a string seja uma representação baseada em raiz diferente de 10. Aqui estão alguns exemplos: Integer.parseInt("-FF", 16) retorna -255 Integer.parseInt("+42", 10) retorna 42 Integer.parseInt("1100110", 2) retorna 102
GO TO FULL VERSION