Автор оригинала: Jonathan Cook.
1. Обзор
При преобразовании строки Java в double , мы обычно используем метод Double.parseDouble(строковое значение) . Этот метод позволяет нам преобразовать String представление заданного double – например, “2.0” – в примитивное double значение.
Как и в большинстве вызовов методов, рекомендуется избегать передачи ссылки null , что, скорее всего, приведет к исключению NullPointerException во время выполнения.
В этом уроке мы рассмотрим несколько способов проверки null перед вызовом Double.parseDouble . Мы начнем с рассмотрения решений, использующих ядро Java, прежде чем рассмотрим некоторые внешние библиотеки.
2. Зачем проверять
Во-первых, давайте разберемся, что произойдет, если мы не проверим значения null при разборе как trying . Давайте начнем с передачи пустой строки :
double emptyString = Double.parseDouble("");
Когда мы запустим этот код, он вызовет исключение java.lang.NumberFormatException :
Exception in thread "main" java.lang.NumberFormatException: empty String at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842) at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110) at java.lang.Double.parseDouble(Double.java:538) ...
Теперь давайте рассмотрим передачу ссылки null :
double nullString = Double.parseDouble(null);
Неудивительно, что a java.lang.На этот раз будет выдано исключение NullPointerException :
Exception in thread "main" java.lang.NullPointerException at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1838) at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110) at java.lang.Double.parseDouble(Double.java:538) ...
Как мы знаем, хорошей практикой может быть использование исключений в коде нашего приложения. Но в целом, мы должны избегать таких непроверенных исключений, которые, вероятно, являются результатом ошибки программирования .
3. Как проверить С помощью Core Java
В этом разделе мы рассмотрим несколько вариантов проверки null или пустых значений с помощью core Java.
3.1. Использование Ванильной Java
Давайте начнем с определения простого метода, который проверит, является ли передаваемое нами значение null или пустой строкой :
private static double parseStringToDouble(String value) { return value == null || value.isEmpty() ? Double.NaN : Double.parseDouble(value); }
Как мы видим, если значение, которое мы пытаемся проанализировать, является null или пустым, этот метод возвращает не число . В противном случае мы вызываем метод Double.parseDouble .
Мы можем взять этот пример на шаг дальше и предложить возможность предоставления предопределенного значения по умолчанию :
private static double parseStringToDouble(String value, double defaultValue) { return value == null || value.isEmpty() ? defaultValue : Double.parseDouble(value); }
Когда мы вызываем этот метод, мы указываем соответствующее значение по умолчанию для возврата, если предоставленное значение null или пустое:
assertThat(parseStringToDouble("1", 2.0d)).isEqualTo(1.0d); assertThat(parseStringToDouble(null, 1.0d)).isEqualTo(1.0d); assertThat(parseStringToDouble("", 1.0d)).isEqualTo(1.0d);
3.2. Использование Опционально
Теперь давайте рассмотрим другое решение с использованием /Необязательного :
private static Optional parseStringToOptionalDouble(String value) { return value == null || value.isEmpty() ? Optional.empty() : Optional.of(Double.valueOf(value)); }
На этот раз мы используем Необязательно в качестве возвращаемого типа . Поэтому, когда мы вызываем этот метод, у нас есть возможность вызвать стандартные методы, такие как is Present() и isEmpty () , чтобы определить, присутствует ли значение:
parseStringToOptionalDouble("2").isPresent()
Мы также можем вернуть значение по умолчанию, используя OrElse метод Необязательно :
parseStringToOptionalDouble("1.0").orElse(2.0d) parseStringToOptionalDouble(null).orElse(2.0d) parseStringToOptionalDouble("").orElse(2.0d)
4. Внешние библиотеки
Теперь, когда у нас есть хорошее понимание того, как проверять null и пустые значения с помощью core Java, давайте взглянем на некоторые внешние библиотеки.
4.1. Google Guava
Первое внешнее решение , которое мы рассмотрим, – это Google Guava , которое доступно на Maven Central :
com.google.guava guava 28.2-jre
Мы можем просто использовать метод Double.TryParse :
Doubles.tryParse(MoreObjects.firstNonNull("1.0", "2.0")) Doubles.tryParse(MoreObjects.firstNonNull(null, "2.0"))
В этом примере мы также используем метод MoreObjects.firstNonNull , который вернет первый из двух заданных параметров, который не является null .
Этот код будет работать нормально в большинстве случаев, но давайте представим другой пример:
Doubles.tryParse(MoreObjects.firstNonNull("", "2.0"))
В этом случае, поскольку пустая Строка не является null , метод вернет null вместо того, чтобы вызывать NumberFormatException . Мы избегаем исключения, но нам все равно придется обрабатывать значение null в какой-то момент в нашем коде приложения.
4.2. Apache Commons Lang NumberUtils
Класс NumberUtils предоставляет множество полезных утилит, облегчающих работу с числами.
Артефакт Apache Commons Lang доступен из Maven Central :
org.apache.commons commons-lang3 3.11
Тогда мы можем просто использовать метод для удвоения из NumberUtils :
NumberUtils.toDouble("1.0") NumberUtils.toDouble("1.0", 1.0d)
Здесь у нас есть два варианта:
- Преобразуйте Строку в double , возвращая 0.0 d в случае сбоя преобразования
- Преобразуйте String в double , предоставляя определенное значение по умолчанию, если преобразование завершится неудачно
Если мы передаем пустое или null значение, 0.0 d возвращается по умолчанию:
assertThat(NumberUtils.toDouble("")).isEqualTo(0.0d); assertThat(NumberUtils.toDouble(null)).isEqualTo(0.0d);
Это лучше, чем в предыдущем примере, так как мы всегда получаем двойной возвращаемое значение независимо от того, что происходит во время преобразования.
4.3. Вавр
И последнее, но не менее важное, давайте взглянем на var.io , который предлагает функциональный подход .
Как всегда, артефакт можно найти на Maven Central :
io.vavr vavr 0.10.2
Опять же, мы определим простой метод, который использует класс vavr Try:
public static double tryStringToDouble(String value, double defaultValue) { return Try.of(() -> Double.parseDouble(value)).getOrElse(defaultValue); }
Мы вызовем этот метод точно так же, как и в других примерах:
assertThat(tryStringToDouble("1", 2.0d)).isEqualTo(1.0d); assertThat(tryStringToDouble(null, 2.0d)).isEqualTo(2.0d); assertThat(tryStringToDouble("", 2.0d)).isEqualTo(2.0d);
5. Заключение
В этом кратком руководстве мы рассмотрели несколько способов проверки null и пустых строк перед вызовом метода Double.parseDouble .
Как всегда, полный исходный код статьи доступен на GitHub .