How can I convert a String
value to an int
type?
"1234" → 1234
How can I convert a String
value to an int
type?
"1234" → 1234
Do it manually:
public static int strToInt(String str) {
int i = 0;
int num = 0;
boolean isNeg = false;
// Check for negative sign; if it's there, set the isNeg flag
if (str.charAt(0) == '-') {
isNeg = true;
i = 1;
}
// Process each character of the string;
while (i < str.length()) {
num *= 10;
num += str.charAt(i++) - '0'; // Minus the ASCII code of '0' to get the value of the charAt(i++).
}
if (isNeg)
num = -num;
return num;
}
Apart from all these answers, I found one new way, although it uses Integer.parseInt()
internally.
By using
import javafx.util.converter.IntegerStringConverter;
new IntegerStringConverter().fromString("1234").intValue()
or
new IntegerStringConverter().fromString("1234")
Although it is a little bit costly as new objects get created.
Just go through the javafx.util.StringConverter<T>
class. It helps to convert any wrapper class value to a string or vice versa.
You can have your own implementations for this, like:
public class NumericStringToInt {
public static void main(String[] args) {
String str = "123459";
int num = stringToNumber(str);
System.out.println("Number of " + str + " is: " + num);
}
private static int stringToNumber(String str) {
int num = 0;
int i = 0;
while (i < str.length()) {
char ch = str.charAt(i);
if (ch < 48 || ch > 57)
throw new NumberFormatException("" + ch);
num = num * 10 + Character.getNumericValue(ch);
i++;
}
return num;
}
}
I have a solution, but I do not know how effective it is. But it works well, and I think you could improve it. On the other hand, I did a couple of tests with JUnit which step correctly. I attached the function and testing:
public static Integer str2Int(String str) {
Integer result = null;
if (null == str || 0 == str.length()) {
return null;
}
try {
result = Integer.parseInt(str);
}
catch (NumberFormatException e) {
String negativeMode = "";
if (str.indexOf('-') != -1)
negativeMode = "-";
str = str.replaceAll("-", "");
if (str.indexOf('.') != -1) {
str = str.substring(0, str.indexOf('.'));
if (str.length() == 0) {
return (Integer) 0;
}
}
String strNum = str.replaceAll("[^\\d]", "" );
if (0 == strNum.length()) {
return null;
}
result = Integer.parseInt(negativeMode + strNum);
}
return result;
}
Testing with JUnit:
@Test
public void testStr2Int() {
assertEquals("is numeric", (Integer) (-5), Helper.str2Int("-5"));
assertEquals("is numeric", (Integer) 50, Helper.str2Int("50.00"));
assertEquals("is numeric", (Integer) 20, Helper.str2Int("$ 20.90"));
assertEquals("is numeric", (Integer) 5, Helper.str2Int(" 5.321"));
assertEquals("is numeric", (Integer) 1000, Helper.str2Int("1,000.50"));
assertEquals("is numeric", (Integer) 0, Helper.str2Int("0.50"));
assertEquals("is numeric", (Integer) 0, Helper.str2Int(".50"));
assertEquals("is numeric", (Integer) 0, Helper.str2Int("-.10"));
assertEquals("is numeric", (Integer) Integer.MAX_VALUE, Helper.str2Int("" + Integer.MAX_VALUE));
assertEquals("is numeric", (Integer) Integer.MIN_VALUE, Helper.str2Int("" + Integer.MIN_VALUE));
assertEquals("Not is numeric", null, Helper.str2Int("czv.,xcvsa"));
/**
* Dynamic test
*/
for (Integer num = 0; num < 1000; num++) {
for (int spaces = 1; spaces < 6; spaces++) {
String numStr = String.format("%0" + spaces + "d", num);
Integer numNeg = num * -1;
assertEquals(numStr + ": is numeric", num, Helper.str2Int(numStr));
assertEquals(numNeg + ": is numeric", numNeg, Helper.str2Int("- " + numStr));
}
}
}
For Android developers ending up here these are various solutions for Kotlin:
// Throws exception if number has bad form
val result1 = "1234".toInt()
// Will be null if number has bad form
val result2 = "1234".toIntOrNull()
// Will be the given default if number has bad form
val result3 = "1234"
.toIntOrNull() ?: -1
// Will be return of the run block if number has bad form
val result4 = "1234"
.toIntOrNull()
?: run {
// some code
// return an Int
}
// Ignores any none-digit character in string
val result5 = "12abc34"
.filter { it.isDigit() }
.joinToString(separator="")
.toIntOrNull()
The two main ways to do this are using the method valueOf()
and method parseInt()
of the Integer
class.
Suppose you are given a String like this
String numberInString = "999";
Then you can convert it into integer by using
int numberInInteger = Integer.parseInt(numberInString);
And alternatively, you can use
int numberInInteger = Integer.valueOf(numberInString);
But the thing here is, the method Integer.valueOf()
has the following implementation in Integer
class:
public static Integer valueOf(String var0, int var1) throws NumberFormatException {
return parseInt(var0, var1);
}
As you can see, the Integer.valueOf()
internally calls Integer.parseInt()
itself.
Also, parseInt()
returns an int
, and valueOf()
returns an Integer
For example, here are two ways:
Integer x = Integer.valueOf(str);
// or
int y = Integer.parseInt(str);
There is a slight difference between these methods:
valueOf
returns a new or cached instance of java.lang.Integer
parseInt
returns primitive int
. The same is for all cases: Short.valueOf
/parseShort
, Long.valueOf
/parseLong
, etc.
public class StringToInteger {
public static void main(String[] args) {
assert parseInt("123") == Integer.parseInt("123");
assert parseInt("-123") == Integer.parseInt("-123");
assert parseInt("0123") == Integer.parseInt("0123");
assert parseInt("+123") == Integer.parseInt("+123");
}
/**
* Parse a string to integer
*
* @param s the string
* @return the integer value represented by the argument in decimal.
* @throws NumberFormatException if the {@code string} does not contain a parsable integer.
*/
public static int parseInt(String s) {
if (s == null) {
throw new NumberFormatException("null");
}
boolean isNegative = s.charAt(0) == '-';
boolean isPositive = s.charAt(0) == '+';
int number = 0;
for (int i = isNegative ? 1 : isPositive ? 1 : 0, length = s.length(); i < length; ++i) {
if (!Character.isDigit(s.charAt(i))) {
throw new NumberFormatException("s=" + s);
}
number = number * 10 + s.charAt(i) - '0';
}
return isNegative ? -number : number;
}
}
Methods to do that:
Integer.parseInt(s)
Integer.parseInt(s, radix)
Integer.parseInt(s, beginIndex, endIndex, radix)
Integer.parseUnsignedInt(s)
Integer.parseUnsignedInt(s, radix)
Integer.parseUnsignedInt(s, beginIndex, endIndex, radix)
Integer.valueOf(s)
Integer.valueOf(s, radix)
Integer.decode(s)
NumberUtils.toInt(s)
NumberUtils.toInt(s, defaultValue)
Integer.valueOf
produces an Integer
object and all other methods a primitive int.
The last two methods are from commons-lang3 and a big article about converting here.
Use Integer.parseInt(yourString)
.
Remember the following things:
Integer.parseInt("1");
// ok
Integer.parseInt("-1");
// ok
Integer.parseInt("+1");
// ok
Integer.parseInt(" 1");
// Exception (blank space)
Integer.parseInt("2147483648");
// Exception (Integer is limited to a maximum value of 2,147,483,647)
Integer.parseInt("1.1");
// Exception (. or , or whatever is not allowed)
Integer.parseInt("");
// Exception (not 0 or something)
There is only one type of exception: NumberFormatException
Well, a very important point to consider is that the Integer parser throws NumberFormatException as stated in Javadoc.
int foo;
String StringThatCouldBeANumberOrNot = "26263Hello"; //will throw exception
String StringThatCouldBeANumberOrNot2 = "26263"; //will not throw exception
try {
foo = Integer.parseInt(StringThatCouldBeANumberOrNot);
} catch (NumberFormatException e) {
//Will Throw exception!
//do something! anything to handle the exception.
}
try {
foo = Integer.parseInt(StringThatCouldBeANumberOrNot2);
} catch (NumberFormatException e) {
//No problem this time, but still it is good practice to care about exceptions.
//Never trust user input :)
//Do something! Anything to handle the exception.
}
It is important to handle this exception when trying to get integer values from split arguments or dynamically parsing something.
I am a little bit surprised that nobody mentioned the Integer constructor that takes String as a parameter.
So, here it is:
String myString = "1234";
int i1 = new Integer(myString);
Of course, the constructor will return type Integer
, and an unboxing operation converts the value to int
.
Note 1: It's important to mention: This constructor calls the parseInt
method.
public Integer(String var1) throws NumberFormatException {
this.value = parseInt(var1, 10);
}
Note 2: It's deprecated: @Deprecated(since="9")
- JavaDoc.
import java.util.*;
public class strToint {
public static void main(String[] args) {
String str = "123";
byte barr[] = str.getBytes();
System.out.println(Arrays.toString(barr));
int result = 0;
for (int i = 0; i < barr.length; i++) {
// System.out.print(barr[i] + " ");
int ii = barr[i];
char a = (char) ii;
int no = Character.getNumericValue(a);
result = result * 10 + no;
System.out.println(result);
}
System.out.println("result:" + result);
}
}
I wrote this fast method to parse a string input into int or long. It is faster than the current JDK 11 Integer.parseInt or Long.parseLong. Although, you only asked for int, I also included the long parser. The code parser below requires that the parser's method must be small for it to operate quickly. An alternative version is below the test code. The alternative version is pretty quick and it does not depend on the size of the class.
This class checks for overflow, and you could customize the code to adapt to your needs. An empty string will yield 0 with my method but that is intentional. You can change that to adapt your case or use as is.
This is only the part of the class where parseInt and parseLong are needed. Note that this only deals with base 10 numbers.
The test code for the int parser is below the code below.
/*
* Copyright 2019 Khang Hoang Nguyen
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* @author: Khang Hoang Nguyen - [email protected].
**/
final class faiNumber{
private static final long[] longpow = {0L, 1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L, 1000000000L,
10000000000L, 100000000000L, 1000000000000L, 10000000000000L, 100000000000000L,
1000000000000000L, 10000000000000000L, 100000000000000000L, 1000000000000000000L,
};
private static final int[] intpow = { 0, 1, 10, 100, 1000, 10000,
100000, 1000000, 10000000, 100000000, 1000000000
};
/**
* parseLong(String str) parse a String into Long.
* All errors throw by this method is NumberFormatException.
* Better errors can be made to tailor to each use case.
**/
public static long parseLong(final String str) {
final int length = str.length();
if (length == 0)
return 0L;
char c1 = str.charAt(0);
int start;
if (c1 == '-' || c1 == '+') {
if (length == 1)
throw new NumberFormatException(String.format("Not a valid long value. Input '%s'.", str));
start = 1;
} else {
start = 0;
}
/*
* Note: if length > 19, possible scenario is to run through the string
* to check whether the string contains only valid digits.
* If the check had only valid digits then a negative sign meant underflow, else, overflow.
*/
if (length - start > 19)
throw new NumberFormatException(String.format("Not a valid long value. Input '%s'.", str));
long c;
long out = 0L;
for ( ; start < length; start++) {
c = (str.charAt(start) ^ '0');
if (c > 9L)
throw new NumberFormatException( String.format("Not a valid long value. Input '%s'.", str) );
out += c * longpow[length - start];
}
if (c1 == '-') {
out = ~out + 1L;
// If out > 0 number underflow(supposed to be negative).
if (out > 0L)
throw new NumberFormatException(String.format("Not a valid long value. Input '%s'.", str));
return out;
}
// If out < 0 number overflow (supposed to be positive).
if (out < 0L)
throw new NumberFormatException(String.format("Not a valid long value. Input '%s'.", str));
return out;
}
/**
* parseInt(String str) parse a string into an int.
* return 0 if string is empty.
**/
public static int parseInt(final String str) {
final int length = str.length();
if (length == 0)
return 0;
char c1 = str.charAt(0);
int start;
if (c1 == '-' || c1 == '+') {
if (length == 1)
throw new NumberFormatException(String.format("Not a valid integer value. Input '%s'.", str));
start = 1;
} else {
start = 0;
}
int out = 0; int c;
int runlen = length - start;
if (runlen > 9) {
if (runlen > 10)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
c = (str.charAt(start) ^ '0'); // <- Any number from 0 - 255 ^ 48 will yield greater than 9 except 48 - 57
if (c > 9)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
if (c > 2)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
out += c * intpow[length - start++];
}
for ( ; start < length; start++) {
c = (str.charAt(start) ^ '0');
if (c > 9)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
out += c * intpow[length - start];
}
if (c1 == '-') {
out = ~out + 1;
if (out > 0)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
return out;
}
if (out < 0)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
return out;
}
}
Test Code Section. This should take around 200 seconds or so.
// Int Number Parser Test;
long start = System.currentTimeMillis();
System.out.println("INT PARSER TEST");
for (int i = Integer.MIN_VALUE; i != Integer.MAX_VALUE; i++){
if (faiNumber.parseInt(""+i) != i)
System.out.println("Wrong");
if (i == 0)
System.out.println("HalfWay Done");
}
if (faiNumber.parseInt("" + Integer.MAX_VALUE) != Integer.MAX_VALUE)
System.out.println("Wrong");
long end = System.currentTimeMillis();
long result = (end - start);
System.out.println(result);
// INT PARSER END */
An alternative method which is also very fast. Note that array of int pow is not used, but a mathematical optimization of multiply by 10 by bit shifting.
public static int parseInt(final String str) {
final int length = str.length();
if (length == 0)
return 0;
char c1 = str.charAt(0);
int start;
if (c1 == '-' || c1 == '+') {
if (length == 1)
throw new NumberFormatException(String.format("Not a valid integer value. Input '%s'.", str));
start = 1;
} else {
start = 0;
}
int out = 0;
int c;
while (start < length && str.charAt(start) == '0')
start++; // <-- This to disregard leading 0. It can be
// removed if you know exactly your source
// does not have leading zeroes.
int runlen = length - start;
if (runlen > 9) {
if (runlen > 10)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
c = (str.charAt(start++) ^ '0'); // <- Any number from 0 - 255 ^ 48 will yield greater than 9 except 48 - 57
if (c > 9)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
if (c > 2)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
out = (out << 1) + (out << 3) + c; // <- Alternatively this can just be out = c or c above can just be out;
}
for ( ; start < length; start++) {
c = (str.charAt(start) ^ '0');
if (c > 9)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
out = (out << 1) + (out << 3) + c;
}
if (c1 == '-') {
out = ~out + 1;
if (out > 0)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
return out;
}
if (out < 0)
throw new NumberFormatException(String.format("Not a valid integer value. Input: '%s'.", str));
return out;
}
An alternate solution is to use Apache Commons' NumberUtils:
int num = NumberUtils.toInt("1234");
The Apache utility is nice because if the string is an invalid number format then 0 is always returned. Hence saving you the try catch block.
There are different ways of converting a string int value into an Integer data type value. You need to handle NumberFormatException for the string value issue.
Integer.parseInt
foo = Integer.parseInt(myString);
Integer.valueOf
foo = Integer.valueOf(myString);
Using Java 8 Optional API
foo = Optional.ofNullable(myString).map(Integer::parseInt).get();
Integer.decode
You can also use public static Integer decode(String nm) throws NumberFormatException
.
It also works for bases 8 and 16:
// base 10
Integer.parseInt("12"); // 12 - int
Integer.valueOf("12"); // 12 - Integer
Integer.decode("12"); // 12 - Integer
// base 8
// 10 (0,1,...,7,10,11,12)
Integer.parseInt("12", 8); // 10 - int
Integer.valueOf("12", 8); // 10 - Integer
Integer.decode("012"); // 10 - Integer
// base 16
// 18 (0,1,...,F,10,11,12)
Integer.parseInt("12", 16); // 18 - int
Integer.valueOf("12", 16); // 18 - Integer
Integer.decode("#12"); // 18 - Integer
Integer.decode("0x12"); // 18 - Integer
Integer.decode("0X12"); // 18 - Integer
// base 2
Integer.parseInt("11", 2); // 3 - int
Integer.valueOf("11", 2); // 3 - Integer
If you want to get int
instead of Integer
you can use:
Unboxing:
int val = Integer.decode("12");
intValue()
:
Integer.decode("12").intValue();
We can use the parseInt(String str)
method of the Integer
wrapper class for converting a String value to an integer value.
For example:
String strValue = "12345";
Integer intValue = Integer.parseInt(strVal);
The Integer
class also provides the valueOf(String str)
method:
String strValue = "12345";
Integer intValue = Integer.valueOf(strValue);
We can also use toInt(String strValue)
of NumberUtils Utility Class for the conversion:
String strValue = "12345";
Integer intValue = NumberUtils.toInt(strValue);
As mentioned, Apache Commons' NumberUtils
can do it. It returns 0
if it cannot convert a string to an int.
You can also define your own default value:
NumberUtils.toInt(String str, int defaultValue)
Example:
NumberUtils.toInt("3244", 1) = 3244
NumberUtils.toInt("", 1) = 1
NumberUtils.toInt(null, 5) = 5
NumberUtils.toInt("Hi", 6) = 6
NumberUtils.toInt(" 32 ", 1) = 1 // Space in numbers are not allowed
NumberUtils.toInt(StringUtils.trimToEmpty(" 32 ", 1)) = 32;
Apart from the previous answers, I would like to add several functions. These are results while you use them:
public static void main(String[] args) {
System.out.println(parseIntOrDefault("123", 0)); // 123
System.out.println(parseIntOrDefault("aaa", 0)); // 0
System.out.println(parseIntOrDefault("aaa456", 3, 0)); // 456
System.out.println(parseIntOrDefault("aaa789bbb", 3, 6, 0)); // 789
}
Implementation:
public static int parseIntOrDefault(String value, int defaultValue) {
int result = defaultValue;
try {
result = Integer.parseInt(value);
}
catch (Exception e) {
}
return result;
}
public static int parseIntOrDefault(String value, int beginIndex, int defaultValue) {
int result = defaultValue;
try {
String stringValue = value.substring(beginIndex);
result = Integer.parseInt(stringValue);
}
catch (Exception e) {
}
return result;
}
public static int parseIntOrDefault(String value, int beginIndex, int endIndex, int defaultValue) {
int result = defaultValue;
try {
String stringValue = value.substring(beginIndex, endIndex);
result = Integer.parseInt(stringValue);
}
catch (Exception e) {
}
return result;
}
Google Guava has tryParse(String), which returns null
if the string couldn't be parsed, for example:
Integer fooInt = Ints.tryParse(fooString);
if (fooInt != null) {
...
}
With Java 11, there are several ways to convert an int
to a String
type:
1) Integer.parseInt()
String str = "1234";
int result = Integer.parseInt(str);
2) Integer.valueOf()
String str = "1234";
int result = Integer.valueOf(str).intValue();
3) Integer constructor
String str = "1234";
Integer result = new Integer(str);
4) Integer.decode
String str = "1234";
int result = Integer.decode(str);
In programming competitions, where you're assured that the number will always be a valid integer, then you can write your own method to parse the input. This will skip all validation-related code (since you don't need any of that) and will be a bit more efficient.
private static int parseInt(String str) {
int i, n = 0;
for (i = 0; i < str.length(); i++) {
n *= 10;
n += str.charAt(i) - 48;
}
return n;
}
private static int parseInt(String str) {
int i = 0, n = 0, sign = 1;
if (str.charAt(0) == '-') {
i = 1;
sign = -1;
}
for (; i < str.length(); i++) {
n *= 10;
n += str.charAt(i) - 48;
}
return sign * n;
}
str = str.trim()
before processing further.This function accepts any param types as input
toString()
public int toInt(Object o) {
// input param is an integer :|
if (o instanceof Integer)
return (int) o;
// input param is (null) so return zero
if (o == null)
return 0;
// input param is boolean, so false = 0 \ true = 1
if (o instanceof Boolean)
return Boolean.TRUE.equals(o) ? 1 : 0;
// convert object to string
String str = "0";
if (o instanceof String) {
str = (String) o;
} else {
try {
str = o.toString();
} catch (Exception e) {}
}
// return zero if the string is empty
if (str == "")
return 0;
// detect and export numbers from the string
try {
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(str);
if ( m.find() ) {
str = m.group(0);
} else { // string not contains any numbers
str = "0";
}
} catch (Exception e) {
str = "0";
}
// java stores integers in 32-bit, so can not store more than 10 digits
if (str.length() > 19) {
str = str.substring(0, 19);
}
// convert string to integer
int result = 0;
try {
result = Integer.parseInt(str);
} catch (Exception e) {}
return result;
}
You can change
catch (Exception e) {}
to
catch (Exception e) { e.printStackTrace(); }
to show more detailed data about errors in logcat
false
""
"00004"
" 51"
"74.6ab.cd"
"foo 654 bar"
This function will change (string)"ab2cd3ef4"
to (int)234
Currently I'm doing an assignment for college, where I can't use certain expressions, such as the ones above, and by looking at the ASCII table, I managed to do it. It's a far more complex code, but it could help others that are restricted like I was.
The first thing to do is to receive the input, in this case, a string of digits; I'll call it String number
, and in this case, I'll exemplify it using the number 12, therefore String number = "12";
Another limitation was the fact that I couldn't use repetitive cycles, therefore, a for
cycle (which would have been perfect) can't be used either. This limits us a bit, but then again, that's the goal. Since I only needed two digits (taking the last two digits), a simple charAt
solved it:
// Obtaining the integer values of the char 1 and 2 in ASCII
int semilastdigitASCII = number.charAt(number.length() - 2);
int lastdigitASCII = number.charAt(number.length() - 1);
Having the codes, we just need to look up at the table, and make the necessary adjustments:
double semilastdigit = semilastdigitASCII - 48; // A quick look, and -48 is the key
double lastdigit = lastdigitASCII - 48;
Now, why double? Well, because of a really "weird" step. Currently we have two doubles, 1 and 2, but we need to turn it into 12, there isn't any mathematic operation that we can do.
We're dividing the latter (lastdigit) by 10 in the fashion 2/10 = 0.2
(hence why double) like this:
lastdigit = lastdigit / 10;
This is merely playing with numbers. We were turning the last digit into a decimal. But now, look at what happens:
double jointdigits = semilastdigit + lastdigit; // 1.0 + 0.2 = 1.2
Without getting too into the math, we're simply isolating units the digits of a number. You see, since we only consider 0-9, dividing by a multiple of 10 is like creating a "box" where you store it (think back at when your first grade teacher explained you what a unit and a hundred were). So:
int finalnumber = (int) (jointdigits*10); // Be sure to use parentheses "()"
And there you go. You turned a String of digits (in this case, two digits), into an integer composed of those two digits, considering the following limitations:
Whenever there is the slightest possibility that the given String does not contain an Integer, you have to handle this special case. Sadly, the standard Java methods Integer::parseInt
and Integer::valueOf
throw a NumberFormatException
to signal this special case. Thus, you have to use exceptions for flow control, which is generally considered bad coding style.
In my opinion, this special case should be handled by returning an empty Optional<Integer>
. Since Java does not offer such a method, I use the following wrapper:
private Optional<Integer> tryParseInteger(String string) {
try {
return Optional.of(Integer.valueOf(string));
} catch (NumberFormatException e) {
return Optional.empty();
}
}
Example usage:
// prints "12"
System.out.println(tryParseInteger("12").map(i -> i.toString()).orElse("invalid"));
// prints "-1"
System.out.println(tryParseInteger("-1").map(i -> i.toString()).orElse("invalid"));
// prints "invalid"
System.out.println(tryParseInteger("ab").map(i -> i.toString()).orElse("invalid"));
While this is still using exceptions for flow control internally, the usage code becomes very clean. Also, you can clearly distinguish the case where -1
is parsed as a valid value and the case where an invalid String could not be parsed.
If you look at the Java documentation you'll notice the "catch" is that this function can throw a
NumberFormatException
, which you can handle:(This treatment defaults a malformed number to
0
, but you can do something else if you like.)Alternatively, you can use an
Ints
method from the Guava library, which in combination with Java 8'sOptional
, makes for a powerful and concise way to convert a string into an int: