在 Java 中如何将 String 转换为 int?

回答 30 浏览 676.5万 2011-04-07

如何将 String 值转换为 int 类型?

"1234"  →  1234
Unknown user 提问于2011-04-07
修改说明:此问题有30个答案和另外82个已删除的答案,其中大部分因重复现有答案而被删除。如果您正在考虑为此问题添加新答案,请确保您已阅读所有现有答案并确认您的答案添加了新的有用内容。Ryan M 2023-03-02
说真的......只是因为你可以想到另一种古怪的方式来进行转换......不要以为告诉每个人这实际上是一件有帮助/有用的事情。Stephen C 2023-03-02
30 个回答
#1楼 已采纳
得票数 4520
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 相结合,提供了一种将字符串转换为 int 的强大而简洁的方法:

import com.google.common.primitives.Ints;

int foo = Optional.ofNullable(myString)
 .map(Ints::tryParse)
 .orElse(0)
Rob Hruska 提问于2011-04-07
Yılmaz Durmaz 修改于2023-02-07
除了捕获 NumberFormatException 之外,用户还应该注意传入的字符串的长度;如果它们足够长以溢出整数,则可能需要考虑使用 Long::parseLong 来代替。Allison 2018-01-17
这是最完整的解释,Allison的评论涵盖了作为字符串传递的长数字的问题!!!!tamegajr 2023-03-29
#2楼
得票数 779

例如,有两种方法:

Integer x = Integer.valueOf(str);
// or
int y = Integer.parseInt(str);

这些方法之间有细微的差别:

  • valueOf 返回 java.lang.Integer 的新实例或缓存实例
  • parseInt 返回原始int

所有情况都是如此:Short.valueOf/parseShortLong.valueOf/parseLong 等。

lukastymo 提问于2011-04-07
nanofarad 修改于2015-06-30
关于两种方法的区别,请参见这个问题hertzsprung 2013-05-19
valueOf方法只是return valueOf(parseInt(string));Paul Verest 2014-10-28
#3楼
得票数 273

嗯,需要考虑的一个非常重要的一点是,整数解析器会抛出 NumberFormatException,如 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.
}

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

Ali Akdurak 提问于2013-04-30
Peter Mortensen 修改于2016-02-16
如何解析“26263Hello”?在这种情况下我想提取 26263463035818_is_not_an_ai 2018-05-16
@user463035818 - 请参阅 docs.oracle。 com/javase/8/docs/api/java/util/regex/… - "([0-9]+)" 的正则表达式模式将“捕获”一个或多个数字 1 到 9 的第一个序列。查看该包中的Matcher 类。Mark Stewart 2018-06-08
#4楼
得票数 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;
    }
Billz 提问于2013-09-11
Dmitriy Popov 修改于2023-07-05
如果输入大于2^32怎么办?如果输入包含非数字字符怎么办?yohm 2014-10-22
程序员在加入劳动力市场时必须学会的一件事(如果不是之前的话)就是永远不要重新发明轮子。这可能是一个有趣的练习,但如果您在商业环境中执行此类操作,请不要指望您的代码能够通过代码审查。Dawood ibn Kareem 2016-01-01
@yohm那些是特殊情况;你可以处理长的和一些正则表达式;不过,到那时你就可以使用 parseInt 了。Billz 2016-01-01
-1 抱歉,但这是一个非常糟糕的算法,有很多限制,没有错误处理,并且有一些奇怪的异常(例如“”出现异常,“-”将产生0,而“+”产生-5)。为什么有人会选择这个而不是Integer.parseInt(s)? - 我明白这是一个面试问题,但是a)这并不意味着你会这样做(这是提问者所问的),b)无论如何,这个答案是一个非常糟糕的例子。SusanW 2016-07-28
-1 因为如果我想解析一个基数 31 的 int 该怎么办? Integer.parseInt(str, 31) 是一个单行代码来做到这一点。有点搞笑的评论,但背后却是严肃的观点。当别人已经投入工作时,永远不要重新发明轮子Nathan Adams 2019-05-01
#5楼
得票数 66

另一种解决方案是使用 Apache Commons NumberUtils:

int num = NumberUtils.toInt("1234");

Apache 实用程序很好,因为如果字符串是无效的数字格式,则始终返回 0。因此节省了 try catch 块。

Apache NumberUtils API 版本 3.4

Ryboflavin 提问于2015-08-27
Jonah Graham 修改于2016-03-05
当解析无效数字时,您很少希望使用 0。wnoise 2016-03-22
@Ryboflavin 不,事实并非如此。其中之一是明确定义的语言语义,另一个是例外etherous 2017-06-01
您还可以使用重载方法指定自己的默认值 NumberUtils.toInt(String, int);Yann Vo 2022-04-20
#6楼
得票数 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();
    
ROMANIA_engineer 提问于2016-03-07
Dmitriy Popov 修改于2023-07-05
#7楼
得票数 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,我们无法进行任何数学运算。

我们以 2/10 = 0.2 的方式将后者(最后一位数字)除以 10(因此为什么是双倍),如下所示:

 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 这样的“魔法”表达式
Oak 提问于2014-03-20
Peter Mortensen 修改于2020-08-21
目前尚不清楚这个答案试图解决什么样的问题,首先,为什么任何人都应该有你描述的限制,其次,为什么你必须查看 ASCII 表,因为你可以简单地使用 '0' 作为字符而不是 48,永远不必关心它的实际数值。第三,使用 double 值的整个绕行完全没有意义,因为您除以十,然后再乘以十。结果就是semilastdigit * 10 + lastdigit,正如小学时引入十进制系统时所学的那样……Holger 2016-03-04
#8楼
得票数 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 和一篇关于此处进行转换。

Dmytro Shvechikov 提问于2017-10-03
Dmytro Shvechikov 修改于2022-11-04
#9楼
得票数 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被解析为有效值的情况和无法解析无效字符串的情况。

Stefan Dollase 提问于2016-04-04
Stefan Dollase 修改于2020-04-12
#10楼
得票数 27

使用 Integer.parseInt(yourString)

请记住以下几点:

Integer.parseInt("1"); // ok

Integer.parseInt("-1"); // ok

Integer.parseInt("+1"); // ok

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

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

Integer.parseInt("1.1"); // 异常(., 或任何不允许的内容)

Integer.parseInt(""); // 异常(不是 0 之类的)

只有一种类型的异常:NumberFormatException

Lukas Bauer 提问于2017-10-06
Peter Mortensen 修改于2019-09-02
#11楼
得票数 24

我们可以使用Integer包装类的parseInt(String str)方法将字符串值转换为整数值。

例如:

String strValue = "12345";
Integer intValue = Integer.parseInt(strVal);

Integer类还提供了valueOf(String str)方法:

String strValue = "12345";
Integer intValue = Integer.valueOf(strValue);

我们还可以使用 NumberUtils 实用程序类toInt(String strValue)用于转换的:

String strValue = "12345";
Integer intValue = NumberUtils.toInt(strValue);
Giridhar Kumar 提问于2015-10-20
Tom 修改于2016-02-16
#12楼
得票数 23

我有一个解决方案,但不知道效果如何。但它运作良好,我认为你可以改进它。另一方面,我使用 JUnit 进行了一些测试,步骤正确。我附上功能和测试:

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

使用 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));
        }
    }
}
fitorec 提问于2014-05-23
Dmitriy Popov 修改于2023-07-05
#13楼
得票数 20

您还可以首先删除所有非数字字符,然后解析整数:

String mystr = mystr.replaceAll("[^\\d]", "");
int number = Integer.parseInt(mystr);

但请注意,这只适用于非负数。

Thijser 提问于2013-10-20
Abhishek Chugh 修改于2019-11-24
这将导致-42被解析为42user289086 2014-10-11
如果您的数据中可能存在非整数,这也会错误解析非整数(例如,4.242)。Ryan M 2023-03-02
#14楼
得票数 19

Google GuavatryParse(String),如果字符串无法解析,则返回 null,例如:

Integer fooInt = Ints.tryParse(fooString);
if (fooInt != null) {
  ...
}
Vitalii Fedorenko 提问于2016-08-06
Peter Mortensen 修改于2019-09-02
#15楼
得票数 13

除了前面的答案之外,我还想添加几个方法。这些是您使用它们时的结果:

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
}

实现:

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;
}
Hoa Nguyen 提问于2016-08-01
Peter Mortensen 修改于2019-09-02
#16楼
得票数 12

如前所述,Apache Commons 的NumberUtils 可以做到这一点。如果无法将字符串转换为 int,则返回0

您还可以定义自己的默认值:

NumberUtils.toInt(String str, int defaultValue)

例子:

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;
Alireza Fattahi 提问于2016-07-26
Peter Mortensen 修改于2019-09-02
#17楼
得票数 11

您可以使用new Scanner("1244").nextInt()。或者询问 int 是否存在:new Scanner("1244").hasNextInt()

Christian Ullenboom 提问于2017-02-28
#18楼
得票数 10

在编程比赛中,您可以确保数字始终是有效的整数,然后您可以编写自己的方法来解析输入。这将跳过所有与验证相关的代码(因为您不需要任何代码)并且效率会更高一些。

  1. 对于有效的正整数:
        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;
        }
  1. 对于正整数和负整数:
        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;
        }
  1. 如果您希望这些数字之前或之后有空格, 然后确保在进一步处理之前执行str = str.trim()
Raman Sahasi 提问
Raman Sahasi 修改于2023-07-05
#19楼
得票数 8

对于普通的String,您可以使用:

int number = Integer.parseInt("1234");

对于StringBuilderStringBuffer,您可以使用:

Integer.parseInt(myBuilderOrBuffer.toString());
Aditya 提问于2016-08-18
Dmitriy Popov 修改于2023-07-05
#20楼
得票数 6

我有点惊讶没有人提到以 String 作为参数的 Integer 构造函数。

所以,这里是:

String myString = "1234";
int i1 = new Integer(myString);

Java 8 - Integer(String).

当然,构造函数将返回类型Integer,并且拆箱操作将值转换为int


注 1:值得一提:此构造函数调用 parseInt 方法。

public Integer(String var1) throws NumberFormatException {
    this.value = parseInt(var1, 10);
}

注 2:已弃用@Deprecated(since="9") - JavaDoc

djm.im 提问于2018-04-23
djm.im 修改于2020-08-28
不推荐使用整数构造函数Basilevs 2020-08-27
#21楼
得票数 2

执行此操作的两种主要方法是使用Integer 类的方法valueOf() 和方法parseInt()

假设给你一个像这样的字符串

String numberInString = "999";

然后你可以使用将其转换为整数

int numberInInteger = Integer.parseInt(numberInString);

或者,您可以使用

int numberInInteger = Integer.valueOf(numberInString);

但这里的问题是,方法Integer.valueOf()Integer类中有以下实现:

public static Integer valueOf(String var0, int var1) throws NumberFormatException {
    return parseInt(var0, var1);
}

正如您所看到的,Integer.valueOf() 在内部调用Integer.parseInt() 本身。 另外,parseInt() 返回intvalueOf() 返回Integer

dxjuv 提问于2020-03-19
Peter Mortensen 修改于2020-08-21
这如何添加任何东西?有几个较旧的答案已经提供了这些方法。请在发布之前阅读现有答案。skomisa 2020-04-12
他正在展示一个人的效率高于另一个人的效率。user1644002 2021-10-08
@user1644002 - 好吧,如果他(和你)这么认为,那么他(可能)是错误的。 JIT 编译器应内联 valueOf -> parseInt 调用,使两个版本同样高效。Stephen C 2022-01-02
#22楼
得票数 1

将字符串 int 值转换为整数数据类型值有多种方法。您需要处理 NumberFormatException 来解决字符串值问题。

  1. Integer.parseInt

     foo = Integer.parseInt(myString);
    
  2. Integer.valueOf

     foo = Integer.valueOf(myString);
    
  3. 使用 Java 8 Optional API

     foo = Optional.ofNullable(myString).map(Integer::parseInt).get();
    
garima garg 提问于2020-04-29
OneCricketeer 修改于2022-02-28
回复“您需要处理字符串值问题的NumberFormatException”:如何处理?通过这三种方法之一完全避免它发生?您能否说得更清楚没有“更新:” 、“编辑:”或类似的)?Peter Mortensen 2020-08-21
这只有两个办法。引入可选不会改变您正在使用 parseIntOneCricketeer 2022-02-28
#23楼
得票数 1

对于最终到达这里的 Android 开发人员,这些是针对 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()
Mahozad 提问于2022-12-02
Mahozad 修改于2023-12-08
#24楼
得票数 0

正如我在 GitHub 上写的

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;
    }
}
duyuanchao 提问于2019-10-22
Peter Mortensen 修改于2020-01-26
#25楼
得票数 0

您可以为此拥有自己的实现,例如:

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;
    }
}
Ajay Singh Meena 提问于2020-07-13
Peter Mortensen 修改于2020-08-21
神奇的数字 48 和 57 是什么?不能使用(命名)常量吗?Peter Mortensen 2020-08-21
#26楼
得票数 0

该函数接受任何参数类型作为输入

  • 然后尝试将其转换toString()
  • 然后通过正则表达式提取整数
  • 并安全地将字符串转换为 int
    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;
    }

你可以改变

catch (Exception e) {}

catch (Exception e) { e.printStackTrace(); }

显示有关 logcat 中错误的更详细数据

可以处理诸如以下的输入:

  • false
  • ""
  • "00004"
  • " 51"
  • "74.6ab.cd"
  • "foo 654 bar"

警告

该函数会将 (string)"ab2cd3ef4" 更改为 (int)234

a55 提问于2023-04-14
Dmitriy Popov 修改于2023-07-05
#27楼
得票数 0
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);
    }
}
Abhijeet Kale 提问于2018-12-25
Dmitriy Popov 修改于2023-07-05
一些解释是适当的。Peter Mortensen 2019-09-02
使用getBytes,您将使用平台的默认字符集并冒着多字节编码的风险。没有理由这样做。另外,这不处理负数。Ryan M 2023-03-02
#28楼
得票数 -1

在 Java 11 中,有多种方法可以将 String 转换为 int 类型:

1) Integer.percent()

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);
Anis KCHAOU 提问于2021-10-23
Peter Mortensen 修改于2022-01-02
#29楼
得票数 -2

我编写了这个快速方法来将字符串输入解析为 int 或 long。它比当前的 JDK 11 Integer.parseInt 或 Long.parseLong 更快。虽然你只要求 int,但我还包括了long解析器。下面的代码解析器要求解析器的方法必须很小才能快速运行。替代版本位于测试代码下方。替代版本非常快,并且不取决于类的规模。

此类检查溢出,您可以自定义代码以适应您的需求。使用我的方法,空字符串将产生 0,但这是故意的。您可以更改它以适应您的情况或按原样使用。

这只是类中需要 parseInt 和 parseLong 的部分。请注意,这仅涉及以 10 为基数的数字。

int 解析器的测试代码如下。

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

测试代码部分。这应该需要大约 200 秒左右。

// 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 */

另一种方法也非常快。请注意,没有使用 int pow 数组,而是通过位移位乘以 10 的数学优化。

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;
}
Kevin Ng 提问于2019-01-21
Peter Mortensen 修改于2019-09-02
另外,澄清一下。幂数组方法运行速度更快的原因是 Java 缓存了此类测试代码的结果。我在现实生活中测试过,使用位移位会更快。Kevin Ng 2019-09-07
为什么if (c > 9)后紧接着是内容完全相同的if (c > 2)Ryan M 2023-03-02
#30楼
得票数 -2

除了所有这些答案之外,我发现了一种新方法,尽管它在内部使用Integer.parseInt()

通过使用

import javafx.util.converter.IntegerStringConverter;

new IntegerStringConverter().fromString("1234").intValue()

或者

new IntegerStringConverter().fromString("1234")

尽管创建新对象的成本有点高。

只需完成javafx.util.StringConverter<T> 类即可。它有助于将任何包装类值转换为字符串,反之亦然。

Yogesh 提问于2020-12-02
Peter Mortensen 修改于2022-01-02
如果您不使用 JavaFX GUI 框架,则不应使用其导入OneCricketeer 2022-02-28