2009-06-04 8 views
26

Я новичок Java-кодер, и я просто прочитал переменную целочисленного класса, которую можно описать тремя способами в API. У меня есть следующий код:Целочисленное сравнение значений

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

Это внутри цикла и просто выводит out_table.
Моя цель - выяснить, как узнать, имеет ли значение целое число count > 0.

Я понимаю, что правильный способ count.compare(0)? или это count.equals(0)?

Я знаю, что неверно count == 0. Это правильно? Есть ли оператор сравнения значений, где его только count=0?

ответ

25

Целые autounboxed, так что вы можете просто сделать

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

Простая ошибка: mmyers. Это autounboxing. –

+0

Да, мой плохой. исправлено это. –

+1

Ummm. На самом деле, нет. ... В других сравнениях это не всегда так. Что делать, если вы сравниваете два целых числа и используете '=='? Затем экземпляры сравниваются, но иногда JVM не кэширует их, поэтому они сообщают о одинаковых значениях как разные. См. Http://stackoverflow.com/questions/10002037/comparing-integer-values-in-java-strange-behavior. – ingyhere

29

Чтобы выяснить, если Integer больше 0, то вы можете:

  • проверить, если compareTo(O) возвращает положительное число:

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

    Но это выглядит довольно глупо, не так ли ? Лучше просто ...

  • использование autoboxing :

    if (count > 0) 
        .... 
    

    Это эквивалентно:

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

    Важно отметить, что "==" оценивается, как это, с Integer операнд unboxed, а не int операнд в коробке. В противном случае count == 0 вернет значение false, если count был инициализирован как new Integer(0) (потому что «==» проверяет ссылочное равенство).

Технически первый пример использует autoboxing (до Java 1.5 вы не могли пройти int к compareTo) и второй пример использует unboxing. Комбинированную функцию часто просто называют «autoboxing» для краткости, которая часто затем распространяется на вызов обоих типов преобразований «autoboxing». Прошу прощения за мое слабое использование терминологии.

+1

В предыдущем примере используется автобоксинг; последний autounboxing. –

+4

+1: Что касается сравнения «==», нужно быть очень осторожным при сравнении * двух * * в штучных * номеров (но не одного бокса и одного примитивного числа), потому что, как упоминалось выше, '==' тесты для справки равенство, а не равенство обернутых значений. –

3

Хотя можно, конечно, использовать метод compareTo на примере целого числа, не ясно, при чтении кода, так что вы, вероятно, следует избегать этого.

Java позволяет использовать Autoboxing (см http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html) непосредственно сравнивать с междунар, так что вы можете сделать:

if (count > 0) { } 

И Integercount экземпляр получает автоматически преобразуются в int для сравнения.

Если у вас возникли проблемы с пониманием этого, проверить ссылку выше, или представить себе, что он делает это:

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

голосовать за информативные ссылки. Имейте в виду, что 'count' должен быть не нулевым. Исключение, созданное при автоматическом распаковке пустого значения, запутывает. – Chadwick

13

Это лучше, чтобы избежать ненужного Autoboxing по 2 причинам.

С одной стороны, это немного медленнее, чем int < int, так как вы (иногда) создаете дополнительный объект;

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

Большая проблема в том, что скрытое Autoboxing может скрыть исключение:

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

Вызов этого метода с null выбросит NullPointerException.

Разделение между примитивами и объектами обертки в java всегда описывалось как kludge для скорости. Автобоксинг почти скрывает это, но не совсем - чище просто следить за типом. Поэтому, если у вас есть объект Integer, вы можете просто позвонить compare() или intValue(), и если у вас есть примитив, просто проверьте значение напрямую.

+0

+1 Для обозначения отрицательных сторон автобокса. Разница в производительности может быть огромной, особенно когда auto (un) бокс в цикле. – helpermethod

12

Вы также можете использовать равен:

Integer a = 0; 

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

что эквивалентно:

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

, а также:

if (a == 0) { 

} 

(компилятор Java автоматически добавляет intValue())

Обратите внимание, что автобоксинг/автообновление может создавать значительные накладные расходы (особенно внутренние петли).

+0

0.equals (a) не компилируется. Или вы говорили не использовать его? –

+0

исправлено, спасибо :-) – dfa

1

Еще одна вещь, на которую нужно обратить внимание, - это то, что вторым значением был другой объект Integer вместо литерала '0', оператор '==' сравнивает указатели объектов и не будет автоматически распаковываться.

т.е.

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

Вы должны создать экземпляр 'a' и' b' с 'New Integer (0)' иначе 'isSame_EqOperator' будет' true' – nolith

+0

Goodpoint @nolith, хотя это связано с кэшированием целых чисел в Java , хорошо объяснили в принятом ответе на http://stackoverflow.com/questions/3131136/integers-caching-in-java. Я изменю свой ответ, чтобы использовать предлагаемое редактирование с комментарием, описывающим, почему явно использовать конструктор. – Sogger

0

хорошо я мог бы быть поздно на это, но я хотел бы поделиться кое-что:

Учитывая вход: System.out.println (isGreaterThanZero (-1));

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

Возвращает ложные

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

Возвращает истинные Так я думаю, что в yourcase 'CompareTo' будет более точным.