[Resolvido] Comparando Integer com ==

11 respostas
C

Pessoal segue o seguinte código:

...
Integer a = 100;
Integer b = 100;

if(a == b)
{
     System.out.println("Iguais !");
}
else
{
     System.out.println("Diferentes !");
}

no caso anterior a saída é “Iguais !”

Ao mudar o

Integer a = 200;
Integer b = 200;

a saída é “Diferentes!”.
Alguém sabe o porque ?

11 Respostas

Rodrigo_Sasaki

Sim.

Para otimização de performance, a classe Integer mantém um cache dos valores mais utilizados.

Se você reparar bem vai ver que é mais comum usarmos valores pequenos: 1, 2, etc…

Esse cache vai desde o valor -128 até 127, então qualquer comparação entre 2 objetos Integer com == nesse campo de valores retornará true.

Qualquer valor fora desse campo não terá o mesmo comportamento.

E

De novo? Isso é um efeito colateral do autoboxing. Quando você escreve

Integer x = 12345;

você está escrevendo algo que é compilado para o seguinte código:

Integer x = Integer.valueOf (12345);

Só que Integer.valueOf(n) é implementado da seguinte forma:
Se o número n estiver fora do intervalo -128 a +127, ele é um “new Integer (n)”. É o caso do número 200.
Se o número n estiver dentro do intervalo -128 a +127, ele puxa o valor de um array estático já pré-alocado, que tem 256 posições. É o caso do número 100.

Deixo a conclusão para você.

Rodrigo_Sasaki

entanglement:
Se o número n estiver dentro do intervalo -128 a +127, ele puxa o valor de um array estático já pré-alocado, que tem 256 posições. É o caso do número 100.

Deixo a conclusão para você.


Realmente, a colocação do entanglement foi muito mais precisa.

Ele não tem um cache interno, embora possa parecer. Ele tem um array estático pré-alocado.

E

Rodrigo Sasaki:
entanglement:
Se o número n estiver dentro do intervalo -128 a +127, ele puxa o valor de um array estático já pré-alocado, que tem 256 posições. É o caso do número 100.

Deixo a conclusão para você.


Realmente, a colocação do entanglement foi muito mais precisa.

Ele não tem um cache interno, embora possa parecer. Ele tem um array estático pré-alocado.

Rodrigo, o que você falou está mais certo, em linhas gerais.
Eu só disse como é implementado (poderia ser implementado de outra forma); você disse como os programadores do JDK pensaram no recurso (é um cache mesmo - só que é bem simples, não aceita modificação ou inclusão, mas continua a ser um cache, de qualquer maneira).

C

Vi esse esse “-128 a +127” no livro de certificação, só nao sabia o que acontecia “por de baixo dos panos”.

Vlw !!

Rodrigo_Sasaki

entanglement:
Rodrigo, o que você falou está mais certo, em linhas gerais.
Eu só disse como é implementado (poderia ser implementado de outra forma); você disse como os programadores do JDK pensaram no recurso (é um cache mesmo - só que é bem simples, não aceita modificação ou inclusão, mas continua a ser um cache, de qualquer maneira).

Entendi.
Pra mim um cache (para ser chamado de cache) dependia dessa possibilidade de alteração dos dados que ele contém.
Problemas de definição :slight_smile:

E

Aliás, de certo modo é importante saber essa particularidade. Eu vou dar um exemplo bem boboca. Digamos que você tenha um array assim:

Integer[] ints = new Integer[1000000];

e eu quisesse inicializar esse array com o valor 123456 em todas as posições. Se fizer isto aqui:

for (int i = 0; i < ints.length; i++) {
    ints[i] = 123456;
}

eu criarei um milhão de objetos java.lang.Integer, todos com o mesmo valor 123456. Como o java.lang.Integer é imutável, na prática o efeito desejado seria também alcançado com:

Integer x = 123456;
for (int i = 0; i < ints.length; i++) {
    ints[i] = x;
}

e nesse caso eu teria apenas 1 objeto java.lang.Integer, sendo referenciado um milhão de vezes.

E

Rodrigo Sasaki:
entanglement:
Rodrigo, o que você falou está mais certo, em linhas gerais.
Eu só disse como é implementado (poderia ser implementado de outra forma); você disse como os programadores do JDK pensaram no recurso (é um cache mesmo - só que é bem simples, não aceita modificação ou inclusão, mas continua a ser um cache, de qualquer maneira).

Entendi.
Pra mim um cache (para ser chamado de cache) dependia dessa possibilidade de alteração dos dados que ele contém.
Problemas de definição :)

De fato, uma tabela interna inalterável (que é o caso desse int[256] criado pela classe java.lang.Integer) é mais parecida com um pool ou então um “look-up table”, não como um cache clássico (que realmente prevê a alteração dos dados contidos - um exemplo clássico é um cache de disco).

Eu chamo de “cache” mesmo porque o intuito é melhorar o acesso a dados (evitando, nesse caso, uma alocação desnecessária de memória).

Rodrigo_Sasaki

É, de acordo com a definição do Wikipedia, realmente esse é o intuito do cache, não é visto uma menção a alteração dos dados, somente à acesso otimizado (mas também não sei o quanto as definições do Wikipedia são confiáveis :))

Wikipedia:
Na área da computação, cache é um dispositivo de acesso rápido, interno a um sistema, que serve de intermediário entre um operador de um processo e o dispositivo de armazenamento ao qual esse operador acede. A vantagem principal na utilização de uma cache consiste em evitar o acesso ao dispositivo de armazenamento - que pode ser demorado -, armazenando os dados em meios de acesso mais rápidos.

thiagof

Fala Marcos!

por que seu nick no GUJ é CristianoGDT ???

Ae, a resposta formal está definida pela própria Oracle… não vou traduzir pra você não amigão hehehe

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer’s part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.

Retirei isto da sessão 5.1.7 da especificação da linguagem, veja o link abaixo…
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

Hehe ontem quando você perguntou eu não estava com tempo para garimpar essa especificação, mas muitas das nossas dúvidas podem ser sanadas ai nesse link.

Grande abraço cara, a gente se vê num próximo post!

lele_vader

Muito louco isso.
Vivendo e aprendendo.

Criado 24 de outubro de 2012
Ultima resposta 24 de out. de 2012
Respostas 11
Participantes 5