Сравнение целых значений
-
11-09-2019 - |
Вопрос
Я начинающий 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
?
Решение
Целые числа распаковываются автоматически, поэтому вы можете просто сделать
if (count > 0) {
....
}
Другие советы
Чтобы выяснить, является ли Integer
больше 0, вы можете:
проверить, если
compareTo(O)
возвращает положительное число:if (count.compareTo(0) > 0) ...
Но это выглядит довольно глупо, не так ли?Лучше просто...
использовать автобокс1:
if (count > 0) ....
Это эквивалентно:
if (count.intValue() > 0) ...
Важно отметить, что»
==
" оценивается следующим образом:Integer
операнд распакованный, а неint
операнд упакован в коробку.В противном случае,count == 0
вернет false, когдаcount
был инициализирован какnew Integer(0)
(потому что "==
"тесты на ссылочное равенство).
1Технически, в первом примере используется автобокс (до Java 1.5 вы не могли передать int
к compareTo
), а во втором примере используется распаковка.Комбинированную функцию часто для краткости называют просто «автобоксингом», а затем часто называют оба типа преобразований «автобоксингом».Прошу прощения за небрежное использование терминологии.
Лучше избегать ненужного автобокса по двум причинам.
Во-первых, это немного медленнее, чем int < int
, поскольку вы (иногда) создаете дополнительный объект;
void doSomethingWith(Integer integerObject){ ...
int i = 1000;
doSomethingWith(i);//gets compiled into doSomethingWith(Integer.valueOf(i));
Более серьезная проблема заключается в том, что скрытый автобокс может скрывать исключения:
void doSomethingWith (Integer count){
if (count>0) // gets compiled into count.intValue()>0
Вызов этого метода с помощью null
бросит NullPointerException
.
Разделение примитивов и объектов-оболочек в Java всегда описывалось как недостаток скорости.Автобокс это почти скрывает, но не совсем — проще просто следить за типом.Итак, если у вас есть объект Integer, вы можете просто позвонить compare()
или intValue()
, и если у вас есть примитив, просто проверьте значение напрямую.
Вы также можете использовать равенства:
Integer a = 0;
if (a.equals(0)) {
// a == 0
}
что эквивалентно:
if (a.intValue() == 0) {
// a == 0
}
а также:
if (a == 0) {
}
(компилятор Java автоматически добавляет intValue())
Обратите внимание, что автоупаковка/автораспаковка может привести к значительным накладным расходам (особенно внутри циклов).
Хотя вы, безусловно, могли бы использовать compareTo
в экземпляре Integer, при чтении кода это неясно, поэтому вам, вероятно, следует избегать этого.
Java позволяет использовать автобокс (см. http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html) для прямого сравнения с int, поэтому вы можете сделать:
if (count > 0) { }
И Integer
пример count
автоматически преобразуется в int
для сравнения.
Если у вас возникли проблемы с пониманием этого, перейдите по ссылке выше или представьте, что он делает это:
if (count.intValue() > 0) { }
Еще одна вещь, на которую следует обратить внимание: если второе значение было другим целочисленным объектом вместо литерала «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
что ж, возможно, я опоздал с этим, но я хотел бы кое-чем поделиться:
Учитывая входные данные:System.out.println(является большим значением (-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;
}
Возвращает true Поэтому я думаю, что в вашем случае 'compareTo' будет более точным.