Хорошо написанная проверка на числа, которые могут быть нулевыми в Java
У меня есть приложение, в котором мне нужно обработать много чисел (целых или длинных), поступающих из внешних источников.
Числа могут быть нулевыми. Если они нулевые, мне всегда нужно конвертировать их в 0.
Проблема кажется тривиальной, но я не хочу писать сотни раз:
if (someNumber == null) {
someNumber = 0;
}
Мне это не нравится по двум причинам:
- Я не люблю писать три строки кода для такой простой задачи, особенно потому, что мне нужно делать это много раз
- Я не люблю "мутировать" someNumber (назначить новое значение для переменной someNumber)
Я попробовал несколько других способов, которые можно увидеть здесь:
public static void main(String[] args) {
Integer zeroOrNull = new Random().nextBoolean() ? 0 : null;
// version1: this is nasty (I already mentioned why)
if (zeroOrNull == null) {
zeroOrNull = 0;
}
// version2: this seems to much for so simple task...
zeroOrNull = Optional.ofNullable(zeroOrNull).orElseGet(() -> 0);
// version3: creating an util might be considerable. Is there already such predefined util ?
zeroOrNull = MyUtil.getValueOrZero(zeroOrNull); // returns value or )
System.out.println(zeroOrNull); // I want 0 here in case of null
}
Какой предпочтительный и хороший способ сделать такой "тест на ноль / преобразование в 0"? Есть ли шанс сделать это преобразование неявно?
5 ответов
Использование i = (i==null)?0:i;
- проверка одной строки
- нет вызова метода
- легко и просто
- нет дополнительной зависимости (в отличие от некоторых других предлагаемых решений)
Поместите эту проверку как можно ближе к источнику номеров, чтобы избежать ненужных дубликатов.
Создавая перегруженные версии Null Checker
public static void main(String args[]) {
Integer intObj = null;
System.out.println("intObj : " + checkNull(intObj));
intObj = 1122222;
System.out.println("intObj : " + checkNull(intObj));
Long longObj = null;
System.out.println("longObj : " + checkNull(longObj));
longObj = 666555556L;
System.out.println("longObj : " + checkNull(longObj));
System.out.println("*********With default value***********");
intObj = null;
System.out.println("intObj : " + checkNull(intObj, 1));
intObj = 1122222;
System.out.println("intObj : " + checkNull(intObj, 1));
longObj = null;
System.out.println("longObj : " + checkNull(longObj, 0L));
longObj = 666555556L;
System.out.println("longObj : " + checkNull(longObj, 0L));
}
static Integer checkNull(Integer obj) {
if (obj == null)
return 0;
return obj;
}
static Long checkNull(Long obj) {
if (obj == null)
return 0L;
return obj;
}
static Integer checkNull(Integer obj, int i) {
if (obj == null)
return i;
return obj;
}
static Long checkNull(Long obj, long l) {
if (obj == null)
return l;
return obj;
}
Простым решением было бы написать вспомогательный метод, как показано ниже:
public static Integer checkNullNumber(Integer i){
if(i == null)
return 0;
return i;
}
Теперь вы можете использовать этот метод где угодно:
zeroOrNull = checkNullNumber(zeroOrNull);
Я не люблю писать три строки кода для такой простой задачи, особенно потому, что мне нужно делать это много раз
if (zeroOrNull == null) zeroOrNull = 0;
Я не люблю "мутировать" someNumber (назначить новое значение для переменной someNumber)
нет способа изменить нулевое значение на "0" без создания нового объекта Integer, который содержит это "0", и эта единственная строка кода делает именно это
Используйте java8 java.util.Optional класс очень эффективен, но не используйте явные нулевые значения, используйте пустой Необязательно
Это мой первоначальный ответ, если "эффективный" имел в виду только "производительность", я ошибся словом, извините.
Смысл в том, что весь процесс кодирования лучше, разработка и выполнение более безопасны.
http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html