【问题标题】:How to return null when list is empty in Java 8?Java 8中列表为空时如何返回null?
【发布时间】:2019-02-19 12:39:40
【问题描述】:

如果作为参数传递的列表为 而不使用 if 语句,我如何更改此方法以使其返回 null

 default String getFiltersExpression(List<WorklistViewDto.Filter> filters) {
    return Optional.ofNullable(filters)
        .map(Collection::stream)
        .orElseGet(Stream::empty)
        .map(WorkListViewMapper::formatValue)
        .map(f -> f.getCriteria() + f.getOperator() + f.getValue())
        .collect(Collectors.joining(" AND ", "(", ")"));
}

【问题讨论】:

  • return Optional...orElse(null);List 不是数组
  • 这里没有数组。你是说名单吗?
  • 是的,对不起。
  • 这里的问题是如果我输入 orElse(null) 或 .orElseGet(Stream::empty) 或 orElseGet(null)。该方法返回一个字符串 = "()"
  • 一个好的旧 if 声明怎么样?

标签: java java-8 java-stream optional


【解决方案1】:

您可以使用 Collectors.collectingAndThen 来做到这一点。

.collect( 
    Collectors.collectingAndThen(
        Collectors.joining(), 
        str->{
            if(str.isEmpty()) return null; 
            return str;
        }
     )
 );

鉴于 OP 的加入声​​明,Collectors.joining(" AND ", "(", ")") 我们可以修改上述内容。

Collectors.collectingAndThen(
    Collectors.joining(" AND "), 
    str->{
            if(str.isEmpty()) return null; 
            return "(" + str + ")";
    })

【讨论】:

  • 我怀疑这里的问题是str 在问题中的joining 操作之后不再为空。它应该只是将"()" 返回到我的can guess
  • @nullpointer 我会编辑它,我的意思是更多地使用另一个收集器。
【解决方案2】:

我建议不要返回 null 而是返回一个 "()" 字符串作为过滤器表达式,您可以在此处为空列表附加一个过滤器:

String getFiltersExpression(List<Filter> filters) {
    return Optional.ofNullable(filters)
            .filter(l -> !l.isEmpty())
            .map(Collection::stream)
            .orElseGet(Stream::empty)
            .map(WorkListViewMapper::formatValue)
            .map(f -> f.getCriteria() + f.getOperator())
            .collect(Collectors.joining(" AND ", "(", ")"));
}

使用 Java-9 语法:

String getFiltersExpressions(List<Filter> filters) {
    return Stream.ofNullable(filters)
            .flatMap(Collection::stream)
            .map(WorkListViewMapper::formatValue)
            .map(f -> f.getCriteria() + f.getOperator() + f.getValue())
            .collect(Collectors.joining(" AND ", "(", ")"));
}

【讨论】:

  • 当列表为空时,OP 想要返回 null,而不是将 null 输入视为空列表。除此之外,第一个变体的.filter(l -&gt; !l.isEmpty()) 步骤已过时。
  • @Holger 同意。这是一个建议,而不是所需的输出。是的,我在想,如果Collection::stream 足以在第一个变体中创建Stream.empty,在这种情况下,OP 的实际代码将执行相同的操作。
【解决方案3】:

另一种方法是仅在列表非空且非空时才开始流式传输:

default String getFiltersExpression(List<WorklistViewDto.Filter> filters) {
    return Optional.ofNullable(filters)
            .filter(fs -> !fs.isEmpty())
            .map(fs -> fs.stream()
                    .map(WorkListViewMapper::formatValue)
                    .map(f -> f.getCriteria() + f.getOperator() + f.getValue())
                    .collect(Collectors.joining(" AND ", "(", ")")))
            .orElse(null);
}

然后你得到 null 而不是 ()

【讨论】:

  • …“如何通过插入 Optional 使我的代码更复杂的另一种情况。与return filters == null || filters.isEmpty()? null: fs.stream() .map(WorkListViewMapper::formatValue) .map(f -&gt; f.getCriteria() + f.getOperator() + f.getValue()) .collect(Collectors.joining(" AND ", "(", ")"));比较
  • @Holger 根据有问题的代码,filters == null 的输出不是() 吗?我一开始是这么想的,后来觉得这个问题有点复杂。
  • @nullpointer 尚不清楚 OP 打算采取哪种行为。该代码示例旨在将null 和空列表视为相同,但问题仅要求空列表的特定行为。您可以以一种或另一种方式解释它。但我之前的评论只是解决了这个答案的代码,展示了如何在没有Optional 的情况下实现同样的简单。
猜你喜欢
  • 2020-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-27
相关资源
最近更新 更多