【问题标题】:Custom Collector to join stream on delimiter, suffix and prefix only if stream is not empty suffix仅当流不是空后缀时,自定义收集器才在分隔符、后缀和前缀上加入流
【发布时间】:2019-10-26 21:18:22
【问题描述】:

我有一个字符串流:

Stream<String> stream = ...;

我想创建一个字符串使用

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

如果流不包含任何元素,我只想返回“No Strings”。

我注意到String java.util.stream.Stream.collect(Collector<? super String, ?, String> collector) 方法采用 java.util.stream.Collector

类型的参数

对于我的项目,我在很多地方都需要这个功能,所以我需要一个实现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(",", "[", "]"));`

这就是我想要发生的事情

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

输出

[]

我想要的输出

No Strings

【问题讨论】:

  • 那么,从创建一个收集器开始并展示你迄今为止的努力如何?这甚至可以很好地进行单元测试!

标签: java java-stream collectors


【解决方案1】:

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

但如果您真的想使用直接收集器,您可以使用the source code of Collections.joiningthe Javadoc of StringJoiner 作为指南来制作自定义收集器:

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

【讨论】:

  • 完美,这就是我想要的
  • 无需创建自定义收集器。可以直接传给Stream.collect(),最后使用toString()stream.collect(() -&gt; new StringJoiner(",", "[", "]").setEmptyValue("No Strings"), StringJoiner::add, StringJoiner::merge).toString();
  • @SamuelPhilipp 对此用例或similar use cases 是正确的,但创建Collector 允许与其他收集器组合,例如groupingBy。最好的选择是创建一个类似于Collectors 中的方法的工厂方法,即带有四个参数的joining。然后,它可以像所有其他人一样使用或组合。
猜你喜欢
  • 2019-12-19
  • 2017-12-07
  • 2014-02-11
  • 1970-01-01
  • 2015-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多