自定义收集器仅当流不是空后缀时才在分隔符、后缀和前缀上加入流

Fer*_*itz 1 java java-stream collectors

我有一个字符串流:

Stream<String> stream = ...;

我想使用创建一个字符串

stream.collect(Collectors.joining(',', '[', ']'))

如果流不包含任何元素,我只想返回“无字符串”。

我注意到该String java.util.stream.Stream.collect(Collector<? super String, ?, String> collector) 方法采用 java.util.stream.Collector<T, A, R> 类型的参数

对于我的项目,我在很多地方都需要这个功能,所以我需要一个实现Collector接口的类。

我知道这可以通过 Stream to a List 然后检查 List.size() == 0 来完成?如果需要,然后再次将列表转换为流。

List<String> list = stream.collect(Collectors.toList());

if (list.size() == 0) {
    return "No Strings";
}
return list.stream().collect(Collectors.joining(",", "[", "]"));`
Run Code Online (Sandbox Code Playgroud)

这就是我想要发生的

List emptyList<String> = new ArrayList<>; System.out.println(emptyList.stream().collect(Collectors.joining(",", "[", "]")));

输出

[]

我想要的输出

No Strings

And*_*ner 5

老实说,我会采用您目前的方法(测试空虚)。

但是如果你真的想使用直接收集器,你可以使用源代码Collections.joiningJavadocStringJoiner作为指南来制作自定义收集器:

Collector.of(
    () -> new StringJoiner(",", "[", "]").setEmptyValue("No strings"),
    StringJoiner::add,
    StringJoiner::merge,
    StringJoiner::toString)
Run Code Online (Sandbox Code Playgroud)

  • 无需创建自定义收集器。您可以将其直接传递给 [`Stream.collect()`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util。 function.Supplier-java.util.function.BiConsumer-java.util.function.BiConsumer-) 并在末尾使用 `toString()`: `stream.collect(() -&gt; new StringJoiner(",", "[ ", "]").setEmptyValue("无字符串"), StringJoiner::add, StringJoiner::merge).toString();` (4认同)
  • @SamuelPhilipp 对这个用例或 [类似用例](/sf/answers/3227129461/) 是正确的,但是创建一个 `Collector` 允许与其他收集器结合,比如 `groupingBy`。最好的选择是创建一个类似于`Collectors` 中的方法的工厂方法,即带有四个参数的`joining`。然后,它可以像所有其他人一样使用或组合。 (4认同)