1. 引言

在Java中,将String转换为intInteger是非常常见的操作。本文将展示处理这个问题的多种方法。

2. Integer.parseInt()

主要的解决方案之一是使用Integer类的专用静态方法parseInt(),它返回一个基本的int值:

@Test
public void givenString_whenParsingInt_shouldConvertToInt() {
    String givenString = "42";

    int result = Integer.parseInt(givenString);

    assertThat(result).isEqualTo(42);
}

默认情况下,parseInt()方法假设给定的String是一个十进制整数。此外,此方法接受另一个参数来更改默认的基数。例如,我们可以这样解析二进制String

@Test
public void givenBinaryString_whenParsingInt_shouldConvertToInt() {
    String givenString = "101010";

    int result = Integer.parseInt(givenString, 2);

    assertThat(result).isEqualTo(42);
}

当然,也可以使用这种方法处理其他基数,如十六进制(16)或八进制(8)。

3. Integer.valueOf()

另一种选择是使用静态Integer.valueOf()方法,它返回一个Integer实例:

@Test
public void givenString_whenCallingIntegerValueOf_shouldConvertToInt() {
    String givenString = "42";

    Integer result = Integer.valueOf(givenString);

    assertThat(result).isEqualTo(new Integer(42));
}

同样,valueOf()方法也接受自定义的基数作为第二个参数:

@Test
public void givenBinaryString_whenCallingIntegerValueOf_shouldConvertToInt() {
    String givenString = "101010";

    Integer result = Integer.valueOf(givenString, 2);

    assertThat(result).isEqualTo(new Integer(42));
}

3.1. 整数缓存

乍看之下,valueOf()parseInt()方法似乎完全相同。大部分情况下确实如此——即使是valueOf()方法也内部委托给了parseInt()方法。

然而,这两个方法之间有一个微妙的区别:valueOf()方法内部使用了一个整数缓存。这个缓存会为-128到127之间的数字返回同一个Integer实例:

@Test
public void givenString_whenCallingValueOf_shouldCacheSomeValues() {
    for (int i = -128; i <= 127; i++) {
        String value = i + "";
        Integer first = Integer.valueOf(value);
        Integer second = Integer.valueOf(value);

        assertThat(first).isSameAs(second);
    }
}

因此,强烈建议使用valueOf()而不是parseInt()来提取装箱的整数,因为它可能会为我们的应用程序带来更好的整体性能。

4. Integer构造函数

你还可以使用Integer的构造函数:

@Test
public void givenString_whenCallingIntegerConstructor_shouldConvertToInt() {
    String givenString = "42";

    Integer result = new Integer(givenString);

    assertThat(result).isEqualTo(new Integer(42));
}

自Java 9以来,这个构造函数已被弃用,以支持其他静态工厂方法,如valueOf()parseInt()。即使在弃用之前,也很少适合使用这个构造函数。我们应该使用parseInt()String转换为int原始类型,或者使用valueOf()将其转换为Integer对象。

5. Integer.decode()

Integer.decode()Integer.valueOf()的工作方式相似,但也能接受不同的数值表示法

@Test
public void givenString_whenCallingIntegerDecode_shouldConvertToInt() {
    String givenString = "42";

    int result = Integer.decode(givenString);

    assertThat(result).isEqualTo(42);
}

6. NumberFormatException

上述所有方法在遇到意外的String值时都会抛出NumberFormatException。这里可以看到这种情况的一个示例:

@Test(expected = NumberFormatException.class)
public void givenInvalidInput_whenParsingInt_shouldThrow() {
    String givenString = "nan";
    Integer.parseInt(givenString);
}

7. 使用Guava

当然,我们不必局限于Java的核心库。使用Guava的Ints.tryParse()可以实现同样的功能,如果无法解析输入,它会返回null

@Test
public void givenString_whenTryParse_shouldConvertToInt() {
    String givenString = "42";

    Integer result = Ints.tryParse(givenString);

    assertThat(result).isEqualTo(42);
}

而且,tryParse()方法也像parseInt()valueOf()一样接受第二个基数参数。

8. 总结

在本文中,我们探讨了将String实例转换为intInteger实例的多种方法。

所有代码示例当然可以在GitHub上找到。