Pergunta

Como faço para multiplicar 10 por um Integer objeto e recuperar o Integer objeto?

Estou procurando a maneira mais simples de fazer isso.

Eu provavelmente faria assim:Obtenha informações de Integer objeto, multiplique-o pelo outro int e crie outro objeto Integer com este valor int.

O código será algo como ...

integerObj = new Integer(integerObj.intValue() * 10);

Mas vi um código onde o autor está fazendo desta forma:Pegue o String de Integer objeto, concatene "0" no final e obtenha Integer objeto de volta usando Integer.parseInt

O código é mais ou menos assim:

String s = integerObj + "0";
integerObj = Integer.parseInt(s);

Existe algum mérito em fazer isso de qualquer maneira?

E qual seria a maneira mais eficiente/limpa em geral e neste caso?

Foi útil?

Solução

Com Java 5 boxe automático, você pode simplesmente fazer:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);

Outras dicas

A abordagem das cordas é divertida, mas quase certamente uma maneira ruim de fazê-lo.

Obter o valor int de um inteiro e criar um novo será muito rápido, enquanto parseInt seria bastante caro para chamar.

No geral, eu concordo com sua abordagem original (que, como outros apontaram, pode ser feita sem tanta confusão se você tiver o autoboxing introduzido no Java 5).

O problema da segunda maneira é a maneira como as Strings são tratadas em Java:

  • "0" é convertido em um objeto String constante em tempo de compilação.
  • Cada vez que esse código é chamado, s é construído como um novo objeto String, e javac converte esse código para String s = new StringBuilder().append(integerObj.toString()).append("0").toString() (StringBuffer para versões mais antigas).Mesmo se você usar o mesmo integerObj, ou seja,

    String s1 = integerObj + "0"; String s2 = integerObj + "0";

    (s1 == s2) seria false, enquanto s1.equals(s2) seria true.

  • Integer.parseInt chamadas internas new Integer() de qualquer maneira, porque Integer é imutável.

Aliás, autoboxing/unboxing é internamente igual ao primeiro método.

Fique longe da segunda abordagem, a melhor aposta seria o autoboxing se você estiver usando Java 1.5, qualquer coisa anterior ao seu primeiro exemplo seria melhor.

A solução usando o método String não é tão boa por vários motivos.Algumas são razões estéticas, outras são práticas.

Do ponto de vista prático, mais objetos são criados pela versão String do que pela forma mais normal (como você expressou em seu primeiro exemplo).

Do ponto de vista estético, acho que a segunda versão obscurece a intenção do código e isso é quase tão importante quanto fazer com que ele produza o resultado desejado.

a resposta do kit de ferramentas acima está correta e é a melhor maneira, mas não fornece uma explicação completa do que está acontecendo.Supondo Java 5 ou posterior:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20

O que você precisa saber é que isso é exatamente o mesmo que fazer:

Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20

Ao realizar a operação (neste caso *=) no objeto 'a', você não está alterando o valor int dentro do objeto 'a', mas na verdade atribuindo um novo objeto a 'a'.Isso ocorre porque 'a' é desempacotado automaticamente para realizar a multiplicação e, em seguida, o resultado da multiplicação é desempacotado automaticamente e atribuído a 'a'.

Inteiro é um objeto imutável.(Todas as classes wrapper são imutáveis.)

Tomemos por exemplo este trecho de código:

static void test() {
    Integer i = new Integer(10);
    System.out.println("StartingMemory: " + System.identityHashCode(i));
    changeInteger(i);
    System.out.println("Step1: " + i);
    changeInteger(++i);
    System.out.println("Step2: " + i.intValue());
    System.out.println("MiddleMemory: " + System.identityHashCode(i));
}

static void changeInteger(Integer i) {
    System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
    System.out.println("ChangeStartValue: " + i);
    i++;
    System.out.println("ChangeEnd: " + i);
    System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}

A saída será:

StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520

Você pode ver que o endereço de memória de 'i' está mudando (seus endereços de memória serão diferentes).

Agora vamos fazer um pequeno teste com reflexão, adicione isto no final do método test():

System.out.println("MiddleMemory: " + System.identityHashCode(i));
try {
    final Field f = i.getClass().getDeclaredField("value");
    f.setAccessible(true);
    f.setInt(i, 15);
    System.out.println("Step3: " + i.intValue());
    System.out.println("EndingMemory: " + System.identityHashCode(i));
} catch (final Exception e) {
    e.printStackTrace();
}

A saída adicional será:

MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520

Você pode ver que o endereço de memória para 'i' não mudou, embora tenhamos alterado seu valor usando reflexão.
(NÃO USE REFLEXÃO ASSIM NA VIDA REAL!!)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top