2009-06-04 19 views
26

Jestem początkującym programistą Java i po prostu czytałem zmienną klasy całkowitej można opisać na trzy różne sposoby w interfejsie API. Mam następujący kod:Porównanie wartości całkowitych

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

Jest wewnątrz pętli i po prostu wyjść out_table.
Moim celem jest dowiedzieć się, jak sprawdzić, czy wartość w liczbie całkowitej count > 0.

Zdaję sobie sprawę, że count.compare(0) jest prawidłowy? czy to jest count.equals(0)?

Wiem, że count == 0 jest niepoprawny. Czy to jest poprawne? Czy istnieje operator porównania wartości, w którym jest to tylko count=0?

Odpowiedz

25

Liczby są autounboxed, więc można po prostu zrobić

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

Ten sam błąd co mmyers. To jest autounboxing. –

+0

tak, moje złe. naprawiono to. –

+1

Ummm. Nie całkiem. ... W innych porównaniach nie zawsze tak jest. Co jeśli porównujesz dwie liczby całkowite i używasz "=="? Następnie instancje są porównywane, ale czasami JVM nie buforuje ich, więc zgłasza identyczne wartości jako różne. Zobacz http://stackoverflow.com/questions/10002037/comparing-integer-values-in-java-strange-behavior. – ingyhere

29

Aby dowiedzieć się, czy Integer jest większa niż 0, można:

  • sprawdzić, czy compareTo(O) zwraca liczbę dodatnią:

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

    Ale to wygląda głupio, prawda ? Lepiej po prostu ...

  • użycie autoboxing :

    if (count > 0) 
        .... 
    

    Jest to odpowiednik:

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

    Ważne jest, aby pamiętać, że "==" jest oceniany tak, ze operand z podpakietem, a nie z operandem z podpakietem Integer, a nie z operandem int. W przeciwnym razie, count == 0 zwróci false, gdy count zostanie zainicjowany jako new Integer(0) (ponieważ "==" testy równości odniesienia).

Technicznie, pierwszy przykład używa autoboxing (przed Java 1.5 nie można zdać int do compareTo) i drugi przykład używa unboxing. Połączona funkcja jest często nazywana po prostu "autoboxing" w skrócie, co jest często rozszerzane na wywoływanie obu typów konwersji "autoboxing". Przepraszam za moje luźne stosowanie terminologii.

+1

Poprzedni przykład wykorzystuje autoboxing; ten ostatni autounboxing. –

+4

+1: Jeśli chodzi o porównanie "==", należy być bardzo ostrożnym przy porównywaniu * dwóch * * pudełkowych * liczb (ale nie jednej liczby pudełkowej i jednej pierwotnej), ponieważ, jak wspominają mmyers, '==' testów dla odniesienia równość, a nie równość zawijanych wartości. –

3

Choć można oczywiście użyć metody compareTo na przykład całkowitą, to nie jest jasne, kiedy czytając kod, więc lepiej unikać tego.

Java umożliwia korzystanie z autoboxing (patrz http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html) porównać bezpośrednio z int, więc można zrobić:

if (count > 0) { } 

I instancja countInteger pobiera automatycznie konwertowane do int dla porównania.

Jeżeli masz problemy ze zrozumieniem tego, sprawdź link powyżej, lub wyobrazić sobie to w ten sposób:

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

do głosowania na linki informacyjne. Należy pamiętać, że 'count' musi mieć wartość inną niż null. Wyjątek utworzony w czasie wykonywania automatycznego rozpakowywania wartości pustej jest mylący. – Chadwick

13

Lepiej uniknąć niepotrzebnego autoboxing dla 2 powodów.

Po pierwsze, jest nieco wolniejsza niż int < int, ponieważ tworzysz (czasami) dodatkowy obiekt;

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

Większym problemem jest to, że można ukryć ukryty autoboxing wyjątki:

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

Wywołanie tej metody z null rzuci NullPointerException.

Podział między prymitywami i obiektami opakowania w języku Java był zawsze opisywany jako kumulacja prędkości. Autoboxing prawie to ukrywa, ale nie do końca - jest czystszy, aby śledzić typ. Więc jeśli masz obiekt Integer, możesz po prostu zadzwonić pod numer compare() lub intValue(), a jeśli masz prymityw, po prostu sprawdź wartość bezpośrednio.

+0

+1 Wymienienie negatywnych stron autounboxingu. Różnica w wydajności może być ogromna, zwłaszcza gdy auto (un) boksuje w pętlach. – helpermethod

12

Można również użyć równa:

Integer a = 0; 

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

co jest równoważne:

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

a także:

if (a == 0) { 

} 

(kompilator Javy automatycznie dodaje intValue())

Należy pamiętać, że autoboxing/autounboxing może wprowadzić znaczny narzut (zwłaszcza wewnątrz pętli).

+0

0.equals (a) nie kompiluje się. A może chciałeś go nie używać? –

+0

naprawiono, dziękuję :-) – dfa

1

Jeszcze jedną rzeczą, na którą należy zwrócić uwagę, jest to, że druga wartość to inny obiekt typu Integer zamiast literalnego "0", operator "==" porównuje wskaźniki obiektów i nie będzie automatycznie rozpakowywać.

tj:

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

Musisz utworzyć instancję 'a' i' b' z 'New Integer (0)' w przeciwnym wypadku 'isSame_EqOperator' będzie' true' – nolith

+0

Goodpoint @nolith, chociaż jest to spowodowane buforowaniem liczb całkowitych w Javie , wyjaśniono dobrze w przyjętej odpowiedzi na http://stackoverflow.com/questions/3131136/integers-caching-in-java. Zmienię moją odpowiedź, aby użyć sugerowanej zmiany z komentarzem opisującym, dlaczego jawnie użyć konstruktora. – Sogger

0

dobrze i może być późno na to, ale chciałbym podzielić się coś:

Biorąc pod uwagę wkład: System.out.println (isGreaterThanZero (-1));

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

Zwraca fałszywe

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

Zwraca true więc myślę, że w yourcase 'CompareTo' będzie bardziej dokładne.