Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Overview

When converting a Java String to a double, we'll typically use the Double.parseDouble(String value) method. This method allows us to convert a String representation of a given double – for example, “2.0” – to a primitive double value.

As with most method calls, it's good practice to avoid passing a null reference, which will likely result in a NullPointerException at runtime.

In this tutorial, we'll explore several ways we can check for null before invoking Double.parseDouble. We'll start by considering solutions using core Java before looking at some external libraries.

2. Why Check

First, let's understand what happens if we don't check for null values when parsing a String. Let's begin by passing an empty String:

double emptyString = Double.parseDouble("");

When we run this code, it will throw a 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)
	...

Now let's consider passing a null reference:

double nullString = Double.parseDouble(null);

Unsurprisingly, a java.lang.NullPointerException will be thrown this time:

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)
	...

As we know, it can be good practice to use exceptions in our application code. But in general, we should avoid these kinds of unchecked exceptions, which are likely the result of a programming error.

3. How to Check With Core Java

In this section, we'll take a look at several options to check for null or empty values using core Java.

3.1. Using Vanilla Java

Let's start by defining a simple method that will check if the value we pass is null or an empty String:

private static double parseStringToDouble(String value) {
    return value == null || value.isEmpty() ? Double.NaN : Double.parseDouble(value);
}

As we can see, if the value we are trying to parse is null or empty this method returns not a number. Otherwise, we invoke the Double.parseDouble method.

We can take this example a step further and offer the possibility of supplying a predefined default:

private static double parseStringToDouble(String value, double defaultValue) {
    return value == null || value.isEmpty() ? defaultValue : Double.parseDouble(value);
}

When we invoke this method, we supply an appropriate default to return if the supplied value is null or empty:

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. Using Optional

Now let's take a look at a different solution with the usage of Optional:

private static Optional parseStringToOptionalDouble(String value) {
    return value == null || value.isEmpty() ? Optional.empty() : Optional.of(Double.valueOf(value));
}

This time, we're using Optional as a return type. Therefore, when we invoke this method, we then have the possibility to call standard methods such as isPresent() and isEmpty() to determine if a value is present:

parseStringToOptionalDouble("2").isPresent()

We can also return a default value using the orElse method of Optional:

parseStringToOptionalDouble("1.0").orElse(2.0d) 
parseStringToOptionalDouble(null).orElse(2.0d) 
parseStringToOptionalDouble("").orElse(2.0d)

4. External Libraries

Now that we have a good understanding of how to check for null and empty values using core Java, let's take a look at some external libraries.

4.1. Google Guava

The first external solution we'll look at is Google Guava, which is available on Maven Central:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.2-jre</version>
</dependency>

We can simply use the Doubles.tryParse method:

Doubles.tryParse(MoreObjects.firstNonNull("1.0", "2.0"))
Doubles.tryParse(MoreObjects.firstNonNull(null, "2.0"))

In this example, we also use the MoreObjects.firstNonNull method, which will return the first of two given parameters that is not null.

This code will work fine in most cases, but let's imagine a different example:

Doubles.tryParse(MoreObjects.firstNonNull("", "2.0"))

In this case, since the empty String isn't null, the method will return null instead of throwing a NumberFormatException. We avoid the exception, but we'll still have to handle a null value at some point in our application code.

4.2. Apache Commons Lang NumberUtils

The NumberUtils class provides many useful utilities that make it easier to work with numbers.

The Apache Commons Lang artifact is available from Maven Central:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.9</version>
</dependency>

Then we can simply use the method toDouble from NumberUtils:

NumberUtils.toDouble("1.0")
NumberUtils.toDouble("1.0", 1.0d) 

Here, we have two options:

  • Convert a String to a double, returning 0.0d if the conversion fails
  • Convert a String to a double, providing a defined default value if the conversion fails

If we pass an empty or null value, 0.0d is returned by default:

assertThat(NumberUtils.toDouble("")).isEqualTo(0.0d);
assertThat(NumberUtils.toDouble(null)).isEqualTo(0.0d);

This is better than the previous example, as we always get a double return value no matter what happens during the conversion.

4.3. Vavr

Last, but not least, let's take a look at vavr.io, which offers a functional approach.

As always, the artifact can be found on Maven Central:

<dependency>
    <groupId>io.vavr</groupId>
    <artifactId>vavr</artifactId>
    <version>0.10.2</version>
</dependency>

Again, we'll define a simple method that makes use of the vavr Try class:

public static double tryStringToDouble(String value, double defaultValue) {
    return Try.of(() -> Double.parseDouble(value)).getOrElse(defaultValue);
}

We'll invoke this method in exactly the same way as in our other examples:

assertThat(tryStringToDouble("1", 2.0d)).isEqualTo(1.0d);
assertThat(tryStringToDouble(null, 2.0d)).isEqualTo(2.0d);
assertThat(tryStringToDouble("", 2.0d)).isEqualTo(2.0d);

5. Conclusion

In this quick tutorial, we've explored several ways of checking for null and empty strings before invoking the Double.parseDouble method.

As always, the full source code of the article is available over on GitHub.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
2 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Sigmund Kreuzer
Sigmund Kreuzer
8 months ago

A alternative optional way, using map and filter

private static Optional parseStringToOptionalDouble(String value) {
return Optional.ofNullable(value).filter(it -> !it.isEmpty()).map(Double::valueOf);
//return value == null || value.isEmpty() ? Optional.empty() : Optional.of(Double.valueOf(value));
}

Loredana Crusoveanu
8 months ago

Hi Sigmund,
Yes, that’s another, a little more concise way to do this, thanks for adding it.

Comments are closed on this article!