Way to parseInt without try-catch in Java 8?

There doesn't exist anything like this in the standard library afaik, but you can write a method that parses a String into an Optional<Integer> like this:

public static Optional<Integer> parseInt(String toParse) {
    try {
        return Optional.of(Integer.parseInt(toParse));
    } catch (NumberFormatException e) {
        return Optional.empty();
    }
}

Unlike other answers that are now deleted, I don't think this really has to do with Java being backwards-compatible.

Because an empty Optional represents a value that is absent, it would mean that the method actually worked but no results are returned.

However, parsing hello as an integer will not work and has to throw an exception, because it is an error rather than an empty result. Keep in mind that NumberFormatException extends IllegalArgumentException.

More generally speaking, Optional was made for dealing with possibly absent values (instead of using null for that), and not for error handling. Also, Optional doesn't provide any way to know what is the error and why there is one.


I don’t want to speculate why such method does not exist, but if you like neither, perform a pre-test nor catch an exception, you need a re-implementation, e.g.

public static OptionalInt parseInt(String s) {
    if(s.isEmpty()) return OptionalInt.empty();
    final int len = s.length(), limit;
    final boolean negative;
    int i = 0;
    switch(s.charAt(0)) {
        case '-':
            i=1;
            if(len==1) return OptionalInt.empty();
            negative = true;
            limit = Integer.MIN_VALUE;
            break;
        case '+':
            i=1;
            if(len==1) return OptionalInt.empty();
            // fall-through
        default:
            negative = false;
            limit = -Integer.MAX_VALUE;
    }
    final int limitBeforeMul = limit / 10;
    int result = 0;
    for(; i < len; i++) {
        int digit = Character.digit(s.charAt(i), 10);
        if(digit < 0 || result < limitBeforeMul || (result *= 10) < limit + digit)
            return OptionalInt.empty();
        result -= digit;
    }
    return OptionalInt.of(negative? result: -result);
}

This basically does the same as Integer.parseInt, but returns an empty OptionalInt for invalid strings instead of throwing an exception…

As you might notice, the hardest part is to handle numbers close to Integer.MIN_VALUE resp. Integer.MAX_VALUE correctly.

Tags:

Java

Java 8