在Java中,如何将字符串转换为整数?

3493
如何将一个 String 值转换为 int 类型?
"1234"1234

2
此问题已有30个答案和82个被删除的答案,其中大部分是因为重复现有答案而被删除。如果您考虑添加新答案,请确保您已阅读所有现有答案,并确认您的答案添加了新的有用信息。 - Ryan M
6
说真的...仅仅因为你能想到另一种疯狂的转换方式...不要想象告诉每个人这件事实际上是有帮助/有用的。 - Stephen C
31个回答

4518
String myString = "1234";
int foo = Integer.parseInt(myString);

如果你查看Java文档,你会注意到这个函数有一个“捕获”条件,即它可能会抛出NumberFormatException异常,你可以进行处理:

int foo;
try {
   foo = Integer.parseInt(myString);
}
catch (NumberFormatException e) {
   foo = 0;
}

(此处理将格式不正确的数字默认为0,但如果您喜欢,可以执行其他操作。)

或者,您可以使用Guava库中的Ints方法,与Java 8的Optional结合使用,这将产生一种强大而简洁的方法将字符串转换为整数:

import com.google.common.primitives.Ints;

int foo = Optional.ofNullable(myString)
 .map(Ints::tryParse)
 .orElse(0)

43
除了捕获 NumberFormatException 之外,用户还应该注意传入的字符串长度;如果字符串长度足够长以至于会导致整数溢出,那么他们可能需要考虑使用 Long::parseLong。 - Allison
这是最完整的解释,Allison的评论涵盖了将长数字作为字符串传递的问题!!! - tamegajr

779
例如,这里有两种方式:
Integer x = Integer.valueOf(str);
// or
int y = Integer.parseInt(str);

这些方法之间有一点差别:

  • valueOf 返回一个新的或缓存的 java.lang.Integer 实例。
  • parseInt 返回原始类型的 int

对于所有情况都是如此: Short.valueOf/parseShort,Long.valueOf/parseLong, 等等。


88
关于这两种方法的区别,请参见这个问题 - hertzsprung
23
valueOf 方法就是 return valueOf(parseInt(string)); - Paul Verest

273

需要考虑的一个非常重要的点是,正如Javadoc中所述,整数解析器会抛出NumberFormatException异常。

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.
}

当尝试从分割参数或动态解析某些内容时获取整数值时,处理此异常非常重要。


如何解析 "26263Hello"? 我想在这种情况下提取 26263 - 463035818_is_not_a_number
1
@user463035818 - 请参阅https://docs.oracle.com/javase/8/docs/api/java/util/regex/package-summary.html - 正则表达式模式"([0-9]+)"将“捕获”第一个由数字1到9组成的一个或多个数字序列。请查看该包中的Matcher类。 - Mark Stewart

93

手动操作:

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;
}

27
如果输入大于2^32怎么办? 如果输入包含非数字字符怎么办? - yohm
98
作为程序员,加入职场之前或者早期就必须学会的一件事情是永远不要重复发明轮子。虽然这可能是一项有趣的练习,但如果在商业环境下这样做,不要指望你的代码能通过代码审查。 - Dawood ibn Kareem
@yohm 这些是特殊情况;你可以使用 long 和一些正则表达式来处理;然而,那时你可以使用 parseInt。 - Billz
50
抱歉,但这是一个相当糟糕的算法,有很多限制,没有错误处理,还有一些奇怪的异常(例如 "" 会抛出异常,“-”会产生0,“+”会产生-5)。为什么会有人选择这个算法而不是 Integer.parseInt(s) 呢?我理解这是一个面试题的意义,但是a)这并不意味着你必须用这种方式来回答问题(这是提问者所问的),b)这个答案本身就是一个很糟糕的例子。 - SusanW
1
-1 是因为如果我想解析一个31进制的整数怎么办?使用 Integer.parseInt(str, 31) 就可以一行代码搞定。这是一个有点玩笑的评论,但是其背后有一个严肃的观点。当别人已经做好了工作时,永远不要重复发明轮子。 - Nathan Adams

66

另一个解决方案是使用Apache Commons中的NumberUtils:

int num = NumberUtils.toInt("1234");
如果字符串的格式不是有效的数字格式,那么Apache实用程序非常好,因为始终返回0。因此,它可以节省您使用try catch块的时间。 Apache NumberUtils API版本3.4

41
当解析无效数字时,很少希望使用0。 - wnoise
15
不,它们并不相同。其中一个是明确定义的语言语义,另一个是异常情况。 - etherous
1
您也可以使用重载的方法NumberUtils.toInt(String, int);指定自己的默认值。 - Yann Vo

49

Integer.decode

你还可以使用 public static Integer decode(String nm) throws NumberFormatException
它也适用于8进制和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

如果你想得到 `int` 而不是 `Integer`,你可以使用以下代码:
翻译:
  1. 拆箱:

     int val = Integer.decode("12"); 
    
  2. intValue()

     Integer.decode("12").intValue();
    

46

目前我正在为大学的作业做准备,其中我不能使用某些表达方式(例如上面的那些),通过查看ASCII表,我设法完成了它。这是一个更复杂的代码,但它可能有助于像我一样受限制的其他人。

要做的第一件事是接收输入,即数字字符串;我将其称为String number,在本例中,我将使用数字12来举例说明,因此String number = "12";

另一个限制是我不能使用重复循环语句,因此也不能使用for循环语句(它本来是完美的)。这有点限制我们的操作,但这也是目标。由于我只需要最后两个数字,所以一个简单的charAt就解决了它:

 // 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);

有了这些代码,我们只需要查阅表格,然后进行必要的调整:

 double semilastdigit = semilastdigitASCII - 48;  // A quick look, and -48 is the key
 double lastdigit = lastdigitASCII - 48;

现在,为什么要使用双倍?因为有一个非常“奇怪”的步骤。目前我们有两个双精度浮点数,1和2,但我们需要将它转换为12,没有任何数学运算可以做到。

我们按照如下方式将后一个数字(即最后一位)除以10:2/10 = 0.2(因此需要使用双倍):

 lastdigit = lastdigit / 10;

这只是在数字上玩耍。我们将最后一位数字变成了十进制。但现在,看看会发生什么:

 double jointdigits = semilastdigit + lastdigit; // 1.0 + 0.2 = 1.2

不需要深入数学,我们只是在分离数字的单位。你看,由于我们只考虑0-9,因此除以10的倍数就像创建了一个“盒子”来存储它(想想当你的一年级老师向你解释什么是个位和百位时)。所以:

 int finalnumber = (int) (jointdigits*10); // Be sure to use parentheses "()"

这样你就把数字字符串(在这种情况下为两个数字)转换成了由这两个数字组成的整数,考虑以下限制:

  • 没有重复循环
  • 不能使用“魔术”表达式,例如parseInt

13
这个答案试图解决什么问题并不清楚。首先,为什么任何人都需要遵循你所描述的限制,其次,你可以直接使用 '0' 代替 48 而无需查看 ASCII 表来表示字符。第三,使用 double 值的整个过程毫无意义,因为你是先除以十,然后再乘以十。结果就像小学里学的那样,是 semilastdigit * 10 + lastdigit,当十进制系统被介绍时... - Holger

43

实现方法:

  1. Integer.parseInt(s)
  2. Integer.parseInt(s, radix)
  3. Integer.parseInt(s, beginIndex, endIndex, radix)
  4. Integer.parseUnsignedInt(s)
  5. Integer.parseUnsignedInt(s, radix)
  6. Integer.parseUnsignedInt(s, beginIndex, endIndex, radix)
  7. Integer.valueOf(s)
  8. Integer.valueOf(s, radix)
  9. Integer.decode(s)
  10. NumberUtils.toInt(s)
  11. NumberUtils.toInt(s, defaultValue)

Integer.valueOf 会生成一个 Integer 对象,其它所有方法返回基本类型 int。

最后两个方法来自于 commons-lang3,关于字符串转换为整数的大文章在这里


32

只要有可能给定的字符串不包含整数,就必须处理这种特殊情况。不幸的是,标准的Java方法Integer::parseIntInteger::valueOf会抛出NumberFormatException来表示这种特殊情况。因此,您必须使用异常来控制流程,这通常被认为是不良编码风格。

在我看来,应该通过返回一个空的Optional<Integer>来处理这种特殊情况。由于Java没有提供这样的方法,我使用以下包装器:

private Optional<Integer> tryParseInteger(String string) {
    try {
        return Optional.of(Integer.valueOf(string));
    } catch (NumberFormatException e) {
        return Optional.empty();
    }
}

示例用法:

// 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"));

虽然在内部仍然使用异常来控制流程,但使用代码变得非常清晰。此外,您可以清楚地区分将-1解析为有效值的情况和无效字符串无法解析的情况。


26

使用Integer.parseInt(yourString)方法进行转换。

请记住以下内容:

Integer.parseInt("1"); // 正确

Integer.parseInt("-1"); // 正确

Integer.parseInt("+1"); // 正确

Integer.parseInt(" 1"); // 异常(空格)

Integer.parseInt("2147483648"); // 异常(整数最大值为2,147,483,647

Integer.parseInt("1.1"); // 异常(不允许使用.,等符号)

Integer.parseInt(""); // 异常(不是0或其他数字)

只有一种异常类型:NumberFormatException


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接