1. 概述

Java泛型为我们带来了许多好处,其中类型安全是最重要的。例如,我们不能将Integer添加到List<String>中。因此,在处理泛型集合时,我们经常需要将Collection<TypeA>转换为Collection<TypeB>

在这个快速教程中,我们将探讨如何将List<String>转换为List<Integer>

2. 准备一个List<String>实例作为示例输入

首先,让我们初始化一个字符串列表作为输入:

List<String> STRING_LIST = Arrays.asList("1", "2", "3", "4", "5", "6", "7")

如图所示,列表对象包含七个字符串。我们希望将STRING_LIST中的每个字符串元素**转换为Integer**,例如,"1" 转换为 1,"2" 转换为 2,以此类推。最终,我们将得到一个与以下相等的List<Integer>

List<Integer> EXPECTED_LIST = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

在本教程中,我们将介绍三种不同的方法来实现这一点:

  • 使用Java 8的流API
  • 使用Java的for循环
  • 使用Guava

为了简化,我们将使用单元测试断言来验证转换是否按预期工作。

接下来,我们深入了解一下。

3. 使用流API的map()方法

Java流API提供了许多便捷的接口,使我们可以轻松处理Collection对象作为流。它在Java 8及更高版本中可用。如今,当我们启动新项目时,很可能使用Java 8或更高版本。因此,我们将首先看流API的方法。

API中的一个方便方法是map()。我们可以简单地使用map()方法**将List<TypeA>转换为List<TypeB>**:

someList.stream().map( .. the conversion logic.. ).collect(Collectors.toList());

上面的“...转换逻辑...”可以是方法引用lambda表达式

现在,让我们看看如何使用map()方法将List<String>转换为List<Integer>

List<Integer> result = STRING_LIST.stream()
  .map(Integer::valueOf)
  .collect(Collectors.toList());

assertEquals(EXPECTED_LIST, result);

在上面的代码示例中,我们传递了一个方法引用Integer::valueOfmap()。将String转换为Integer有多种方法,此处简化了,我们对每个字符串元素调用了Integer.valueOf()

如果运行,测试通过。所以,流的map()方法解决了问题。

4. 使用for循环

我们已经看到流的map()方法可以解决问题。然而,正如我们提到的,流API仅在Java 8及以上版本可用。因此,如果我们使用较旧的Java版本,我们就无法使用流API。因此,我们需要以不同的方式解决这个问题。

接下来,我们通过简单的for循环进行转换:

List<Integer> result = new ArrayList<>(STRING_LIST.size());
for (String s : STRING_LIST) {
    result.add(Integer.valueOf(s));
}

assertEquals(EXPECTED_LIST, result);

上述代码显示,我们首先创建一个新的List<Integer>对象result,然后通过for循环迭代List<String>列表中的元素,将每个String元素转换为Integer,并将整数添加到result列表中。

如果运行,测试会通过。

5. 使用Guava库

当我们处理集合时,常常需要转换集合的类型,因此一些流行外部库提供了执行转换的实用方法。

在本节中,我们将使用Guava展示如何解决我们的问题。

首先,我们在pom.xml中添加Guava库依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.0.1-jre</version>
</dependency>

当然,我们可以在Maven中央仓库检查最新版本

接下来,我们将使用Guava的Lists.transform()方法来解决问题。顾名思义,transform()方法可以根据提供的“转换函数”将集合转换为不同类型的集合:

List<Integer> result = Lists.transform(STRING_LIST, new Function<String, Integer>() {
    @Override
    public Integer apply(String input) {
        return Integer.valueOf(input);
    }
});

assertEquals(EXPECTED_LIST, result);

如上所述,我们传递了一个匿名的Function对象作为“转换函数”。它告诉transform()方法如何应用转换。再次,我们调用Integer.valueOf()将每个String转换为Integer

如果运行,测试会通过。

6. 总结

在这篇简短的文章中,我们学习了三种将List<String>转换为List<Integer>的方法。如果我们在Java 8或更高版本上工作,流API将是最直接的转换方法。否则,我们可以通过循环或转向外部库(如Guava)来应用转换。

如往常一样,这里展示的所有代码片段都可以在GitHub上找到