2009-06-04 12 views
26

Soy un codificador Java novato y acabo de leer una variable de una clase entera que se puede describir de tres maneras diferentes en la API. Tengo el siguiente código:Comparación del valor entero

if (count.compareTo(0)) { 
      System.out.println(out_table); 
      count++; 
    } 

Esto está dentro de un bucle y simplemente da salida a out_table.
Mi objetivo es averiguar cómo ver si el valor en el número entero count > 0.

Me doy cuenta de que el count.compare(0) es la manera correcta? o es count.equals(0)?

Sé que count == 0 es incorrecto. ¿Es esto correcto? ¿Hay un operador de comparación de valores donde es solo count=0?

Respuesta

25

Los enteros se autounboxed, por lo que sólo pueden hacer

if (count > 0) { 
    .... 
} 
+5

Mismo error que mmyers. Esto es autounboxing. –

+0

sí, mi mal. arregló eso. –

+1

Ummm. Realmente no. ... En otras comparaciones, este no es siempre el caso. ¿Qué sucede si comparas dos enteros y usas '=='? Luego se comparan las instancias, pero a veces la JVM no las almacena en la memoria caché, por lo que informa valores idénticos como diferentes. Ver http://stackoverflow.com/questions/10002037/comparing-integer-values-in-java-strange-behavior. – ingyhere

29

de averiguar si un Integer es mayor que 0, se puede:

  • verificación si compareTo(O) devuelve un número positivo:

    if (count.compareTo(0) > 0) 
        ... 
    

    Pero eso parece bastante tonto, ¿no es cierto ? Mejor solo ...

  • uso autoboxing :

    if (count > 0) 
        .... 
    

    Esto es equivalente a:

    if (count.intValue() > 0) 
        ... 
    

    Es importante tener en cuenta que "==" se evalúa como este, con el operando Integer unboxed en lugar del int operando en caja. De lo contrario, count == 0 devolvería falso cuando count se inicializó como new Integer(0) (porque "==" prueba la igualdad de referencia).

Técnicamente, el primer ejemplo utiliza autoboxing (antes de Java 1.5 no podía dejar pasar una int a compareTo) y el segundo ejemplo utiliza unboxing. La característica combinada a menudo se llama simplemente "autoboxing" para abreviar, que a menudo se extiende a llamar a ambos tipos de conversiones "autoboxing". Me disculpo por mi poco uso de la terminología.

+1

El ejemplo anterior es el uso de autoboxing; el último autounboxing. –

+4

+1: Con respecto a la comparación '==', uno debe ser muy cauteloso al comparar * dos * * números encuadrados * (pero no un número encuadrado y uno primitivo), porque, como mencionó mmyers, '==' prueba de referencia igualdad, no igualdad de los valores envueltos. –

3

Aunque ciertamente se podría utilizar el método compareTo en una instancia de enteros, no queda claro al leer el código, por lo que probablemente debería evitar hacerlo.

de Java le permite utilizar autoboxing (ver http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html) para comparar directamente con un int, por lo que puede hacer:

if (count > 0) { } 

Y el Integer ejemplo count se convertirá automáticamente en un int para la comparación.

Si usted está teniendo problemas para entender esto, echa un vistazo en el enlace anterior, o imaginar que está haciendo esto:

if (count.intValue() > 0) { } 
+0

hasta vote por enlaces informativos. Tenga en cuenta que 'count' tiene que ser no nulo. La excepción producida en el desencadenamiento automático de tiempo de ejecución de un valor nulo es confusa. – Chadwick

13

Es mejor evitar autoboxing innecesaria por 2 razones.

Por un lado, es un poco más lento que int < int, ya que (a veces) está creando un objeto adicional;

void doSomethingWith(Integer integerObject){ ... 
    int i = 1000; 
    doSomethingWith(i);//gets compiled into doSomethingWith(Integer.valueOf(i)); 

El problema más grande es que autoboxing oculto puede ocultar excepciones:

void doSomethingWith (Integer count){ 
    if (count>0) // gets compiled into count.intValue()>0 

llamada a este método con null lanzará una NullPointerException.

La división entre primitivos y objetos de envoltura en java siempre se describió como un obstáculo para la velocidad. Autoboxing casi oculta esto, pero no del todo, es más limpio simplemente para realizar un seguimiento del tipo. Por lo tanto, si tiene un objeto Integer, puede simplemente llamar al compare() o al intValue(), y si tiene la primitiva, simplemente verifique el valor directamente.

+0

+1 Por mencionar los lados negativos del autoenvasado. La diferencia de rendimiento puede ser enorme, especialmente cuando el auto (un) boxeo en bucles. – helpermethod

12

También puede utilizar es igual a:

Integer a = 0; 

if (a.equals(0)) { 
    // a == 0 
} 

el cual es equivalente a:

if (a.intValue() == 0) { 
    // a == 0 
} 

y también:

if (a == 0) { 

} 

(el compilador de Java añade automáticamente intValue())

Tenga en cuenta que el autoboxing/autounboxing puede introducir una sobrecarga significativa (especialmente en el interior de los bucles).

+0

0.equals (a) no compila. ¿O estabas diciendo que no lo usas? –

+0

arreglado, gracias :-) – dfa

1

Una cosa más a tener en cuenta es que si el segundo valor era otro objeto Integer en lugar de un literal '0', el operador '==' compara los punteros del objeto y no lo hará automáticamente.

es decir:

Integer a = new Integer(0); 
Integer b = new Integer(0); 
int c = 0; 

boolean isSame_EqOperator = (a==b); //false! 
boolean isSame_EqMethod = (a.equals(b)); //true 
boolean isSame_EqAutoUnbox = ((a==c) && (a.equals(c)); //also true, because of auto-unbox 

//Note: for initializing a and b, the Integer constructor 
// is called explicitly to avoid integer object caching 
// for the purpose of the example. 
// Calling it explicitly ensures each integer is created 
// as a separate object as intended. 
// Edited in response to comment by @nolith 
+0

Debe instanciar 'a' y' b' con 'Nuevo entero (0)' de lo contrario 'isSame_EqOperator' será' verdadero' – nolith

+0

Goodpoint @nolith, aunque esto se debe al almacenamiento en caché de enteros en Java , bien explicado en la respuesta aceptada a http://stackoverflow.com/questions/3131136/integers-caching-in-java. Cambiaré mi respuesta para usar su edición sugerida con un comentario que describa por qué usar explícitamente el constructor. – Sogger

0

bien puede ser que sea tarde en esto, pero me gustaría compartir algo:

Dada la entrada: System.out.println (isGreaterThanZero (-1));

public static boolean isGreaterThanZero(Integer value) { 
    return value == null?false:value.compareTo(0) > 0; 
} 

devoluciones falsas

public static boolean isGreaterThanZero(Integer value) { 
    return value == null?false:value.intValue() > 0; 
} 

Devuelve true así que creo que en yourcase 'compareTo' será más preciso.

Cuestiones relacionadas