自定义收集器仅在流不是空后缀的情况下才能在定界符,后缀和前缀上加入流

时间:2019-06-12 11:13:19

标签: 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

的参数

对于我的项目,我需要在许多地方使用此功能,因此需要一个实现Collector接口的类。

我知道这可以通过Stream到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 = new ArrayList<String>; System.out.println(emptyList.steam().collect(Collectors.joining(',', '[', ']')));

输出

[,]

我想要的输出

No Strings

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:0)

我还建议您使用已有的if语句。要随后生成字符串,您也可以使用String.join()

List<String> list = stream.collect(Collectors.toList());
if (list.isEmpty()) {
    return "No Strings";
}
return "[" + String.join(",", list) + "]";

如果您不希望,也可以使用Optional来防止这种情况:

return Optional.of(stream.collect(Collectors.toList()))
        .filter(l -> !l.isEmpty())
        .map(l -> "[" + String.join(",", l) + "]")
        .orElse("No Strings");

但是我不认为这更具可读性。