2009-06-04 8 views
26

Ich bin ein Neuling Java-Coder und ich lese gerade eine Variable einer Ganzzahl-Klasse kann drei verschiedene Möglichkeiten in der API beschrieben werden. Ich habe den folgenden Code:Integer-Wert Vergleich

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

Diese innerhalb einer Schleife ist, und nur ausgibt out_table.
Mein Ziel ist es herauszufinden, wie der Wert in Integer count > 0 zu sehen ist.

Ich realisiere die count.compare(0) ist der richtige Weg? oder ist es count.equals(0)?

Ich weiß, dass count == 0 falsch ist. Ist das richtig? Gibt es einen Wertvergleichsoperator, bei dem nur count=0?

Antwort

25

Integers autounboxed sind, so können Sie tun nur

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

Derselbe Fehler wie mmyers. Dies ist Auto-Boxen. –

+0

Ja, mein Schlechter. repariere das. –

+1

Ummm. Nicht wirklich. ... In anderen Vergleichen ist das nicht immer der Fall. Was ist, wenn Sie zwei Ganzzahlen vergleichen und '==' verwenden? Dann werden die Instanzen verglichen, aber die JVM speichert sie manchmal nicht, sodass sie identische Werte als unterschiedlich meldet. Siehe http://stackoverflow.com/questions/10002037/comparing-integ-values-in-java-strange-behavior. – ingyhere

29

Um herauszufinden, ob ein Integer größer als 0 ist, können Sie:

  • überprüfen, ob compareTo(O) gibt eine positive Zahl:

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

    Aber das sieht ziemlich dumm, es nicht ? Besser nur ...

  • Verwendung autoboxing :

    if (count > 0) 
        .... 
    

    Dies entspricht:

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

    Es ist wichtig zu beachten, dass "==" wie folgt bewertet wird, mit der Integer-Operand entkoppelt und nicht der int-Operand eingerahmt. Andernfalls würde count == 0 false zurückgeben, wenn count als new Integer(0) initialisiert wurde (weil "==" auf Referenzgleichheit testet).

Technisch gesehen ist das erste Beispiel verwendet autoboxing und das zweite Beispiel verwendet unboxing (vor Java 1.5 Sie keine int zu compareTo passieren könnten). Die kombinierte Funktion wird oft einfach als "Autoboxing" bezeichnet, das dann oft dazu verwendet wird, beide Arten von Konvertierungen als "Autoboxing" zu bezeichnen. Ich entschuldige mich für meine laxe Verwendung der Terminologie.

+1

Das vorherige Beispiel verwendet Autoboxing; Letzteres Auto-Boxing. –

+4

+1: In Bezug auf den '== 'Vergleich, sollte man sehr vorsichtig sein beim Vergleich von * zwei * * boxed * Zahlen (aber nicht eine Boxed und eine primitive Zahl), weil, wie mmyers erwähnt,' == 'Tests als Referenz Gleichheit, nicht Gleichheit der umhüllten Werte. –

3

Obwohl Sie sicherlich die compareTo Methode auf einem Integer-Instanz verwenden könnte, dann ist es nicht klar, wann Lesen des Codes, so sollten Sie vielleicht vermeiden, so zu tun.

Java ermöglicht es Ihnen, Autoboxing (siehe http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html) zu verwenden, um direkt mit einem int zu vergleichen, so dass Sie tun können:

if (count > 0) { } 

Und die Integer Instanz count wird zu einem int für den Vergleich automatisch konvertiert.

Wenn Sie Probleme haben, dies zu verstehen, überprüfen Sie den Link oben aus, oder sich vorstellen, es ist dies zu tun:

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

up Abstimmung für informative Links. Beachten Sie, dass "count" nicht null sein muss. Die Ausnahme, die während der Laufzeit erzeugt wird, wenn ein Nullwert automatisch aufgehoben wird, ist verwirrend. – Chadwick

13

Es ist besser, um unnötige Autoboxing aus 2 Gründen zu vermeiden.

Zum einen ist es etwas langsamer als int < int, da Sie (manchmal) ein zusätzliches Objekt erstellen;

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

Das größere Problem ist, dass versteckte Autoboxing Ausnahmen verstecken kann:

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

Aufruf dieser Methode mit null ein NullPointerException werfen wird.

Die Aufteilung zwischen Primitiven und Wrapper-Objekten in Java wurde immer als Kludur für die Geschwindigkeit beschrieben. Autoboxing verbirgt dies fast, aber nicht ganz - es ist sauberer, nur um den Typ zu verfolgen. Also, wenn Sie ein Integer-Objekt haben, können Sie einfach compare() oder intValue() aufrufen, und wenn Sie das Primitive haben, überprüfen Sie einfach den Wert direkt.

+0

+1 Für die negativen Seiten des Autounboxing. Der Leistungsunterschied kann enorm sein, insbesondere beim automatischen (Un) Boxen in Loops. – helpermethod

12

Sie können auch gleich verwenden:

Integer a = 0; 

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

das entspricht:

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

und auch:

if (a == 0) { 

} 

(der Java-Compiler fügt automatisch intValue())

Beachten Sie, dass Autoboxing/Auto-Boxing einen erheblichen Overhead (insbesondere innerhalb von Schleifen) verursachen kann.

+0

0.equals (a) kompiliert nicht. Oder hast du gesagt, es nicht zu benutzen? –

+0

behoben, danke :-) – dfa

1

Noch eine Sache zu beachten ist, wenn der zweite Wert ein anderes Integer-Objekt anstelle einer Literal '0' war, vergleicht der '==' Operator die Objektzeiger und wird nicht automatisch aufheben.

dh:

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

Sie müssen 'a' und' b' mit 'New Integer (0) instanziieren' sonst 'isSame_EqOperator' ist' true' – nolith

+0

Goodpoint @nolith, obwohl dies auf das Zwischenspeichern von Ganzzahlen in Java zurückzuführen ist , erklärte gut in der akzeptierten Antwort zu http://stackoverflow.com/questions/3131136/integers-caching-in-java. Ich werde meine Antwort ändern, um Ihre vorgeschlagene Bearbeitung mit einem Kommentar zu verwenden, der beschreibt, warum der Konstruktor explizit verwendet werden soll. – Sogger

0

gut ich auf diesem spät sein könnte, aber ich möchte etwas teilen:

Da der Eingang: System.out.println (isGreaterThanZero (-1));

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

Returns falsch

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

Gibt true zurück Also ich denke, in yourcase 'compareTo' genauer sein wird.