ParseInt
A Java String
cannot be used like an int
—it cannot be incremented. It contains chars, textual data. With parseInt
we convert a string
to an int
.
ParseInt
can lead to complex problems—it throws a NumberFormatException
on invalid data. Many exceptions will lead to slower program performance.
ParseInt
, parseUnsignedInt
This program uses the parseInt
method and its friend parseUnsignedInt
. For the string
"1000," we get the number 1000.
int
variable to the result of the parseInt
method. This is the parsing result.parseUnsignedInt
does nearly the same thing as parseInt
, but does not allow negative numbers in the argument string
.public class Program { public static void main(String[] args) { String value = "1000"; // Parse with parseInt: the string can be negative. int result = Integer.parseInt(value); System.out.println(result); System.out.println(result + 1); // Parse with parseUnsignedInt: minus sign not allowed. int result2 = Integer.parseUnsignedInt(value); System.out.println(result2); System.out.println(result2 + 2); } }1000 1001 1000 1002
NumberFormatException
This error is caused by trying to parse an invalid number string
. For example the string
"turnip" cannot be converted into an integer.
NumberFormatException
, we can develop a method that tests for validity before calling parseInt
.public class Program { public static void main(String[] args) { String invalid = "turnip"; // This causes a NumberFormatException. int result = Integer.parseInt(invalid); } }Exception in thread "main" java.lang.NumberFormatException: For input string: "turnip" at java.lang.NumberFormatException.forInputString(Unknown Source) at java.lang.Integer.parseInt(Unknown Source)....
ParseUnsignedInt
errorThe unsigned method here cannot handle strings that have a leading minus sign. A leading plus is accepted. The result is always a positive number.
public class Program { public static void main(String[] args) { String test = "-100"; // ParseInt handles signed integers. int value = Integer.parseInt(test); System.out.println(value == -100); // ParseUnsignedInt throws an Exception. value = Integer.parseUnsignedInt(test); } }true Exception in thread "main" java.lang.NumberFormatException: Illegal leading minus sign on unsigned string -100. at java.lang.Integer.parseUnsignedInt....
We can handle errors caused by Integer.parseInt
with a try and catch construct. This is slow if an error occurs, but it works. We can assign a default value in the catch block.
public class Program { public static void main(String[] args) { String invalid = "turnip"; int result = -100; // A default result. try { // This throws an exception because the string is invalid. result = Integer.parseInt(invalid); } catch (NumberFormatException n) { // ... Do nothing. } System.out.println(result); // Prints default result. } }-100
We introduce a method that scans strings for digit characters. With isValidNumber
, we see if a number will be parsed without an exception before calling parseInt
.
Character.isDigit
method returns true for valid digits, and false otherwise.public class Program { static boolean isValidNumber(String value) { // Loop over all characters in the String. // ... If isDigit is false, this method too returns false. for (int i = 0; i < value.length(); i++) { if (!Character.isDigit(value.charAt(i))) { return false; } } return true; } public static void main(String[] args) { String[] values = { "cat", "100", "200", "dog" }; for (String value : values) { // If this is a valid number, parse it. if (isValidNumber(value)) { int number = Integer.parseInt(value); System.out.println(number); } } } }100 200
ParseDouble
A double
can be parsed in the same way as an int
. But we must use parseDouble
on the Double
class
. This will handle numbers with a decimal place.
public class Program { public static void main(String[] args) { String data = "12.01"; // Parse the double in the String. double value = Double.parseDouble(data); if (value == 12.01) { System.out.println("String converted to Double!"); } } }String converted to Double!
We can avoid exceptions when calling Integer.parseInt
by validating data. Here we see 2 versions of parsing logic. With the data array, they do the same thing.
isValidNumber
method. We call this method before using parseInt
.parseInt
with try and catch.public class Program { static boolean isValidNumber(String value) { // Return true if all characters are digits. for (int i = 0; i < value.length(); i++) { if (!Character.isDigit(value.charAt(i))) { return false; } } return true; } public static void main(String[] args) { String[] values = { "cat", "100", "200", "dog" }; long t1 = System.currentTimeMillis(); // Version 1: call isValidNumber before parseInt. for (int i = 0; i < 1000000; i++) { int sum = 0; for (String v : values) { if (isValidNumber(v)) { sum += Integer.parseInt(v); } } } long t2 = System.currentTimeMillis(); // Version 2: handle Exception on invalid numbers. for (int i = 0; i < 1000000; i++) { int sum = 0; for (String v : values) { try { sum += Integer.parseInt(v); } catch (Exception ex) { // ... Do nothing. } } } long t3 = System.currentTimeMillis(); // ... Times. System.out.println(t2 - t1); System.out.println(t3 - t2); } } 72 ms: isValidNumber, Integer.parseInt 1686 ms: try, Integer.parseInt, catch
We develop an optimized parsing algorithm. ParseIntFast
here progresses from left to right in a string
. It converts each char
to an integer by subtracting 48.
parseIntFast
multiplies by 10—so the digit to the left of the current one is ten times greater in the result int
.parseIntFast
method to parse numbers character-by-character.Integer.parseInt
method that is part of the Integer class
.parseIntFast
method requires less than half the time of Integer.parseInt
. It may also avoid exceptions.public class Program { public static int parseIntFast(String value) { // Loop over the string, adjusting ASCII value to integer value. // ... Multiply previous result by 10 as we progress. int result = 0; for (int i = 0; i < value.length(); i++) { result = 10 * result + (value.charAt(i) - 48); } return result; } public static void main(String[] args) { String test = "1234"; System.out.println(parseIntFast(test)); long t1 = System.currentTimeMillis(); // Version 1: use optimized parse method. for (int i = 0; i < 10000000; i++) { int v = parseIntFast(test); if (v != 1234) { return; } } long t2 = System.currentTimeMillis(); // Version 2: use built-in parse method. for (int i = 0; i < 10000000; i++) { int v = Integer.parseInt(test); if (v != 1234) { return; } } long t3 = System.currentTimeMillis(); // ... Times. System.out.println(t2 - t1); System.out.println(t3 - t2); } }1234 74 ms parseIntFast 168 ms Integer.parseInt
Console
inputWe can use Integer.parseInt
to parse the input read from a terminal (console) window. The try and catch blocks are required to avoid failures.
With parseInt
, and custom helper methods, we handle numeric data in strings. We can read in integers from text files and convert them into usable numbers. This step is powerful and common.