1. 引言

将字符串列表转换为以逗号分隔的字符串作为Java开发人员来说仍然是一个热门话题,因为我们在日常开发中经常遇到这种情况。在这个教程中,我们将学习如何使用四种不同的方法将字符串列表转换为逗号分隔的字符串。

2. 使用Java 8及以上版本

我们将利用Java 8及以后版本提供的三个不同类及其方法来进行转换。

让我们以以下列表作为接下来示例的输入:

List<String> arraysAsList = Arrays.asList("ONE", "TWO", "THREE");

2.1. String

首先,我们将使用String类,它提供了许多字符串处理工具,并提供了join()转换方法:

String commaSeparatedString = String.join(",", arraysAsList);

assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");

2.2. StringJoiner

其次,我们将使用StringJoiner类,它的构造函数接受一个字符序列分隔符参数:

StringJoiner stringJoiner = new StringJoiner(",");
arraysAsList.forEach(stringJoiner::add);
String commaSeparatedString = stringJoiner.toString();

assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");

还有一个构造函数接受一个字符序列分隔符、前缀和后缀:

StringJoiner stringJoinerWithDelimiterPrefixSuffix = new StringJoiner(",", "[", "]");
arraysAsList.forEach(stringJoinerWithDelimiterPrefixSuffix::add);
String commaSeparatedStringWithDelimiterPrefixSuffix = stringJoinerWithDelimiterPrefixSuffix.toString();

assertThat(commaSeparatedStringWithDelimiterPrefixSuffix).isEqualTo("[ONE,TWO,THREE]");

2.3. Collectors

第三,Collectors类提供了各种实用的和合并方法,具有不同的签名。

首先,我们将看到如何在Stream上应用collect()方法,使用Collectors.joining()方法,该方法接受一个字符序列分隔符作为输入:

String commaSeparatedUsingCollect = arraysAsList.stream()
  .collect(Collectors.joining(","));

assertThat(commaSeparatedUsingCollect).isEqualTo("ONE,TWO,THREE");

在下一个示例中,我们将看到如何使用map()方法将列表中的每个对象转换为字符串,然后应用collect()Collectors.joining()方法:

String commaSeparatedObjectToString = arraysAsList.stream()
  .map(Object::toString)
  .collect(Collectors.joining(","));

assertThat(commaSeparatedObjectToString).isEqualTo("ONE,TWO,THREE");

接下来,我们将使用map()方法将列表元素转换为字符串,然后应用collect()Collectors.joining()方法:

String commaSeparatedStringValueOf = arraysAsList.stream()
  .map(String::valueOf)
  .collect(Collectors.joining(","));

assertThat(commaSeparatedStringValueOf).isEqualTo("ONE,TWO,THREE");

现在,我们将像上面那样使用map(),然后使用Collectors.joining()方法,它接受一个字符序列分隔符、前缀和后缀:

String commaSeparatedStringValueOfWithDelimiterPrefixSuffix = arraysAsList.stream()
  .map(String::valueOf)
  .collect(Collectors.joining(",", "[", "]"));

assertThat(commaSeparatedStringValueOfWithDelimiterPrefixSuffix).isEqualTo("[ONE,TWO,THREE]");

最后,我们将看到如何使用reduce()方法而不是collect()进行转换:

String commaSeparatedUsingReduce = arraysAsList.stream()
  .reduce((x, y) -> x + "," + y)
  .get();

assertThat(commaSeparatedUsingReduce).isEqualTo("ONE,TWO,THREE");

3. 使用Apache Commons Lang

另一种选择是使用Apache Commons Lang库提供的实用类,而不是Java自带的。

为了使用Apache的StringUtils类,我们需要在pom.xml文件中添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

join()方法有多种实现,接受一系列元素、值的迭代器以及多种形式的分隔符,如字符串或字符:

String commaSeparatedString = StringUtils.join(arraysAsList, ",");

assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");

如果join()方法接收到的是一个对象数组,它还会接受一个起始索引和一个结束索引作为参数:

String commaSeparatedStringIndex = StringUtils.join(arraysAsList.toArray(), ",", 0, 3);

assertThat(commaSeparatedStringIndex).isEqualTo("ONE,TWO,THREE");

4. 使用Spring Core

Spring Core库同样提供了此类转换的实用类。

首先,我们需要在pom.xml文件中添加依赖,以便使用Spring的Core StringUtils类:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.22</version>
</dependency>

Spring的Core StringUtils类提供了一个方法collectionToCommaDelimitedString(),默认使用逗号作为分隔符,接收一个Collection作为转换参数:

String collectionToCommaDelimitedString = StringUtils.collectionToCommaDelimitedString(arraysAsList);

assertThat(collectionToCommaDelimitedString).isEqualTo("ONE,TWO,THREE");

另一个方法collectionToDelimitedString(),接收一个要转换的Collection和一个字符串分隔符作为参数:

String collectionToDelimitedString = StringUtils.collectionToDelimitedString(arraysAsList, ",");

assertThat(collectionToDelimitedString).isEqualTo("ONE,TWO,THREE");

5. 使用Google Guava

最后,我们将使用Google Guava库。

为了使用Google的Guava Joiner类,我们需要在pom.xml文件中添加依赖:

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

Google的Guava Joiner类提供了我们可以连续应用的各种方法。

第一个方法是on(),它接受一个字符串作为分隔符参数,然后是join()方法,它接受一个要转换的Iterable作为参数:

String commaSeparatedString = Joiner.on(",")
  .join(arraysAsList);

assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");

让我们以包含一些null值的另一个列表为例:

List<String> arraysAsListWithNull = Arrays.asList("ONE", null, "TWO", null, "THREE");

考虑到这一点,我们可以在on()join()方法之间使用其他方法,其中之一是skipNulls()方法。我们可以使用它来避免转换Iterable中的null值:

String commaSeparatedStringSkipNulls = Joiner.on(",")
  .skipNulls()
  .join(arraysAsListWithNull);

assertThat(commaSeparatedStringSkipNulls).isEqualTo("ONE,TWO,THREE");

另一种选择是使用useForNull(),它接受一个字符串值作为参数,用于替换Iterable中要转换的null值:

String commaSeparatedStringUseForNull = Joiner.on(",")
  .useForNull(" ")
  .join(arraysAsListWithNull);

assertThat(commaSeparatedStringUseForNull).isEqualTo("ONE, ,TWO, ,THREE");

6. 结论

在这篇文章中,我们看到了将字符串列表转换为逗号分隔字符串的不同示例。最终,选择哪个库和实用类取决于我们的具体需求。

如往常一样,本文的所有完整代码示例可在GitHub上找到。