4 different ways to use Integer.parseInt in Java

Overview

It is a daily job for programmers to convert some data type to another. This article will explore approaches to convert a given Java String object to an integer value (primitive type int).

Integer.parseInt

Thanks to the standard Java Class Library, we have parseInt and parseUnsignedInt methods on the Integer class that parse the string argument as a signed or unsigned decimal integer.

  /**
     * Java method demonstrating simple use of parseInt to convert String to integer
     */
    private static void simpleConversion() {

        int sample1 = Integer.parseInt("0");    // returns 0
        int sample2 = Integer.parseInt("47");   // returns 47
        int sample3 = Integer.parseInt("+4");   // returns 4
        int sample4 = Integer.parseInt("-4");   // returns -4
        int sample5 = Integer.parseInt("-0");   // returns 0

        /**
         * The below line prints
         *             0
         *             47
         *             4
         *             -4
         *             0
         */
        IntStream.of(sample1, sample2, sample3, sample4, sample5).forEach(System.out::println);

//        .parseInt below throws an unchecked NumberFormatException because " 0 xx" is not a valid integer
        int sample6 = Integer.parseInt(" 0 xx"); //throws Unchecked NumberFormatException
    }

As we can see, Integer.parseInt though useful, can be used directly only in very limited use cases where it is guaranteed that the incoming String will be an integer.

Let’s look at some options to harden our String to int conversion logic.

Option 1 – Continue using Integer.parseInt and handle NumberFormatException

    private int convertStringToInt(String str, int defaultValue){
        try {
            return Integer.parseInt(str); //return the int if parsing succeeds
        }
        catch(NullPointerException | NumberFormatException e){
//            log the unsuccessful parse if necessary
            return defaultValue; //return default value otherwise
        }
    }

The caller will be required to provide a default value in case the passed string is not parseable. If the passed string is null or not a valid integer, this method will return the defaultValue.
We can add some simple sanitization of the String to increase the probability of successful conversion using the String.trim method.

Our previous code would have returned defaultValue for " 123 " but the below code will successfully parse and return 123 if passed " 123 "

    private int convertStringToInt(String str, int defaultValue){
        try {
            return Integer.parseInt(str.trim()); //return the int if parsing succeeds
        }
        catch(NullPointerException | NumberFormatException e){
            return defaultValue; //return default value otherwise
        }
    }

Option 2 – Simple Regular Expression and avoiding NumberFormatException


    private static final String simpleIntegerRegEx = "\\d+";
    private static int convertUsingSimpleRegEx(String str, int detaultValue){

//       Sanitize the string. Take care of the case where str may be null. Remove leading & trailing spaces
        str = str == null? "":str.trim();
        
//        Parse and return the int only if str matches the format for an integer otherwise return defaultValue
        return str.matches(simpleIntegerRegEx) ? Integer.parseInt(str) : detaultValue;
    }

In the above example, we first want to reinitialize str to handle null cases and trim any leading and/or trailing spaces. This step is done using – str = str == null? "":str.trim(); and will make sure we don’t encounter an NPE or NullPointerException later in the method.

The next line return str.matches(simpleIntegerRegEx) ? Integer.parseInt(str) : detaultValue; does a few things

  • Checks whether the sanitized string is in an "integer" format
  • Invokes and returns the output of Integer.parseInt only if the format check passes
  • Returns the defaultValue that the caller of the method wants to be returned otherwise

Advantages of this approach –

  • Cleaner code
  • We are not relying on Exceptions to control flow in the regular happy path

Disadvantages of this approach –

  • Matching Strings against regular expressions is expensive
  • Overall performance of this approach will be slower than the previous approach

Option 3 – Character by character traversal of the input String

Now let’s suppose we are given a text (String), and we have to identify the first integer in the string. For example, given input string " sample text to find the integer 123 and not 456" our method should be able to extract int value 123
Here is one way to do that-

  • We can traverse the string character by character and check if each character is a digit or not.
  • As soon as we find the first digit, we record its position and continue traversing until we encounter digits.
  • As soon as we encounter a non-digit character, we stop traversing, and then we use the recorded position of start and end of digit characters to get a substring
  • This substring can be safely converted to int using parseInt

Here is the code snippet for the above approach –

private static void charBycharFindDigits(){
    String sampleString = " sample text to find the integer 123 and not 456 ";

    int integerStartIndex = 0, integerEndIndex = 0;

//        find the position of the first digit
    while (integerStartIndex < sampleString.length() && !Character.isDigit(sampleString.charAt(integerStartIndex)))
        integerStartIndex++;
    
//        We have found the first digit. Continue traversing until we continue to see digits.
    integerEndIndex = integerStartIndex;
    while (integerEndIndex < sampleString.length() && Character.isDigit(sampleString.charAt(integerEndIndex)))
        integerEndIndex++;

//    evaluates result to 123
    int result = Integer.parseInt(sampleString.substring(integerStartIndex, integerEndIndex));
    
    System.out.println("First Integer:" + result);
}

One limitation of the above code is that it will not detect negative integers. i.e. the above snippet will continue to print ”123” even if the sample string was "String sampleString = " sample text to find the integer -123 and not 456 "; For text -123 in a given string, we obviously want our code to return integer value -123 and not 123
We can fix this by adding the below snippet AFTER evaluating result

//check if our found integer is actually a negative integer
if(integerStartIndex> 1 && sampleString.charAt(integerStartIndex-1) == '-')
    result = -result;
System.out.println("First Integer:" + result);

Option 4 – Using Pattern Matcher

Now let’s suppose we are given a text (String), and we have to identify all the integers in the string.
For example, given input string "This is a string with not 1 but -3 integers. Third one is a random 3421" our method should be able to extract an integer array with values 1, -3 and 3421

We can use Matcher with an appropriate regular expression to find all the integers in a given string. Here how the code snippet would look like –

 private static int[] extractUsingPatternMatcher(String str){
     Matcher matcher = Pattern.compile("([-+]?[0-9]+)").matcher(str);
     return matcher.results().mapToInt((mr -> Integer.parseInt(mr.group()))).toArray();
 }

We are using regular expression "([-+]?[0-9]+)" to match patterns in the string. Each match will represent an integer (positive or negative). The next line, matcher.results() returns a Stream of the matched results, each of which represents an integer but in a String literal format. We then use Streams.mapToInt() to convert the MatchResult stream to an IntStream. The IntStream is then converted to an integer array using toArray()

The above can be tested by passing it a String and then printing the array it returns.

int[] detectedInts = extractUsingPatternMatcher("This is a string with not 1 but -3 integers. third one is a random 3421");

// print the contents of an integer array using Streams
Arrays.stream(detectedInts).forEach(System.out::println);

The above snippet will print

1
-3
3421

Conclusion

In this article, we have looked at various scenarios for converting string or part(s) of the string to int and solutions for each of the scenarios along with their nuances.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.