I have a stream operation (Java 8) that is meant to parse a bunch of strings into doubles and take a sum. Some of the strings are empty, but I don't believe any are null. I've added a filter
operation to filter the empty ones out before they reach Double.parseDouble()
where they might cause an error, but the filter doesn't seem to work.
My code:
double myTotal= myObjectList.stream()
.map(myObject::getAmount)
.peek( s -> System.out.println("before filter: " + s) )
.filter( s -> !s.isEmpty() )
.peek( s -> System.out.println("after filter: " + s) )
.mapToDouble(Double::parseDouble)
.reduce(0D,Double::sum);
This is in a JSP, and the JSP fails to compile. According to the error page, the exception occurs in the last line (.reduce(0D,Double::sum);
), but the "root cause" is a "java.lang.NumberFormatException: empty String
" -- Double.parseDouble()
is encountering empty strings.
I have tried several permutations of the filter
operation, including some that checked for null and some that checked !s.equals("")
and the like. I added the peek
operations for debugging and it is clear that an empty string is being printed both before and after the filter
line.
What am I doing wrong? Is there a better way to filter out values that can't be parsed to doubles?
String with white spaces, technically not empty, cause an exception to be raised with the message "empty string". As another poster pointed out, the solution is to trim the input string first.
This confusion is the result of an unfortunate documentation bug in sun.misc.FloatingDecimal.readJavaFormatString
which is indirectly called by Double.parseDouble
. Although the semantics of String#empty
is
Returns
true
if, and only if,length()
is 0.
the implementation of readJavaFormatString
actually trims the input string first, then computes the length, and throws the NumberFormatException
with the (very misleading) message "empty string":
in = in.trim(); // don't fool around with white space.
// throws NullPointerException if null
int len = in.length();
if ( len == 0 ) {
throw new NumberFormatException("empty String");
}
This can be readily observed by executing:
Double.parseDouble(" ");