2008-09-05 26 views
8

¿Cómo multiplico 10 en un objeto Integer y recupero el objeto Integer?Cómo multiplicar 10 a un objeto "Entero" en Java?

Estoy buscando la mejor manera de hacerlo.

Probablemente lo haga de esta manera: Obtenga int del objeto Integer, multiplíquelo con el otro int y cree otro objeto Entero con este valor int.

Código será algo así como ...

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

Pero, vi un código en el que el autor está haciendo de esta manera: Obtener el String del objeto Integer, concatenar "0" al final y a continuación, obtener Integer objeto de nuevo mediante el uso de Integer.parseInt

el código es algo como esto:

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

¿está el ¿Hay algún mérito en hacerlo de cualquier manera?

¿Y cuál sería la forma más eficiente/más adecuada en general y en este caso?

+0

También le aconsejaría que verifique si el uso de Integer es REALMENTE necesario. Joshua señaló que usar primitivas es MUCHAS veces más rápido en Java efectivo. Entonces, si puedes, sigue con ** int **. –

+0

Usar entero es en realidad una restricción de diseño. La idea es obtener un objeto entero y tengo que actualizar eso. Por lo tanto, no puedo deshacerme de eso :) – Jagmal

+0

Actualizar un objeto entero existente no va a suceder sin reflexión vudú. (El entero, al igual que otros tipos de envoltura primitiva, es inmutable). Lo mejor que puede hacer razonablemente, y lo que cualquier ejemplo sensato hará, es reemplazarlo con otro objeto. Que es lo suficientemente bueno para la mayoría de los casos, pero significa 'void modifyInteger (Integer i)' no hará nada que valga la pena. – cHao

Respuesta

25

Con Java 5 de autoboxing, sólo tiene que hacer:

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

No se recomienda el uso del constructor Integer. Use autoboxing o valueOf() en su lugar ... –

7

El enfoque de la secuencia es divertido, pero casi seguro que es una mala manera de hacerlo.

Obtener el valor int de un Entero, y crear uno nuevo será muy rápido, mientras que como sería bastante caro llamar.

En general, estoy de acuerdo con su enfoque original (que, como han señalado otros, se puede hacer sin tanto desorden si tiene autoboxing como se introdujo en Java 5).

1

Mantener alejado de la segunda aproximación, la mejor opción sería la autoboxing si está usando Java 1.5, cualquier cosa antes de su primer ejemplo sería mejor .

1

La solución que utiliza el método String no es tan buena por una variedad de razones. Algunas son razones estéticas, otras son prácticas.

En un frente práctico, la versión String crea más objetos que la forma más normal (como lo ha expresado en su primer ejemplo).

Desde un punto de vista estético, creo que la segunda versión oscurece la intención del código y eso es casi tan importante como lograr que produzca el resultado que desea.

3

El problema con la segunda forma es la forma de cuerdas se manejan de Java:

  • "0" se convierte en un objeto de cadena constante en tiempo de compilación.
  • Cada vez que se llama a este código, s se construye como un nuevo objeto String, y javac lo convierte a String s = new StringBuilder().append(integerObj.toString()).append("0").toString() (StringBuffer para versiones anteriores). Incluso si usa el mismo integerObj, es decir,

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

    (s1 == s2) habría false, mientras s1.equals(s2) habría true.

  • Integer.parseInt llamadas internas new Integer() de todos modos, porque Integer es inmutable.

BTW, autoboxing/unboxing es internamente el mismo que el primer método.

+0

'Integer.parseInt (...) 'no tiene que crear un objeto Integer, funciona directamente con un' int' primitivo. –

0

La respuesta del kit de herramientas anterior es correcta y la mejor manera, pero no proporciona una explicación completa de lo que está sucediendo. Suponiendo Java 5 o posterior:

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

Lo que hay que saber es que este es exactamente el mismo que hacer:

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

Mediante la realización de la operación (en este caso * =) en el objeto 'a', no está cambiando el valor int dentro del objeto 'a', sino que realmente asigna un nuevo objeto a 'a'. Esto se debe a que 'a' se desempaqueta automáticamente para realizar la multiplicación, y luego el resultado de la multiplicación se coloca automáticamente en la caja y se asigna a 'a'.

Entero es un objeto inmutable. (Todas las clases de envoltura son inmutables.)

Tomemos por ejemplo este pedazo 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)); 
} 

la salida 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 

se puede ver la dirección de memoria para 'i' es cambiando (sus direcciones de memoria serán diferentes).

Ahora vamos a hacer una pequeña prueba con la reflexión, añade esta en el extremo del 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(); 
} 

La salida adicional será:

MiddleMemory: 190331520 
Step2: 15 
MiddleMemory: 190331520 

se puede ver que el la dirección de memoria para 'i' no cambió, aunque cambiamos su valor usando la reflexión.
(NO USE LA REFLEXIÓN DE ESTA MANERA EN LA VIDA REAL !!)