如何在Java 8中使用带有null和空检查的平面地图合并多个列表?

Ash*_*inK 3 java java-8

我使用Stream.of(..)&合并多个列表,然后flatMap在同一列表上执行以下操作以收集合并的列表,如下所示:

class Foo{

    List<Entity> list1;
    List<Entity> list2;
    List<Entity> list3;

    //getters & setters

}
Run Code Online (Sandbox Code Playgroud)
Foo foo = getFoo();
Predicate<Entity> isExist = //various conditions on foo ;
List<Bar> bars = Stream
        .of(foo.getList1(), foo.getList2(), foo.getList3())
        .flatMap(Collection::stream)
        .filter(isExist)
        .map(entity -> getBar(entity))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

第一个问题

Stream.of(..)检查 nonNullnotEmpty吗?如果ans

第二个问题

我怎样才能对上面代码中得到的所有内容执行nonNullnotEmpty检查?因此,只要这三个列表全部合并,它基本上会忽略&避免?listsfoonullempty listNullPointerException

Eug*_*ene 5

 Stream
    .of(foo.getList1(), foo.getList2(), foo.getList3())
    .filter(Objects::nonNull)
    ....
Run Code Online (Sandbox Code Playgroud)

或由Holger指出并在flatMapjava-doc中指定:

如果映射流为null,则使用空流。

因此,您可以执行以下操作:

 Stream
    .of(foo.getList1(), foo.getList2(), foo.getList3())
    .flatMap(x -> x == null? null : x.stream())
Run Code Online (Sandbox Code Playgroud)

  • 也许您应该先回答问题的第一部分。由于`flatMap`对于空列表将做正确的事情,因此无需对其进行测试。因此对于问题的第二部分,在flatMap之前添加一个.filter(Objects :: nonNull)即可。或者只使用一个`.flatMap(list-&gt; list == null?null:list.stream())`。 (3认同)
  • @AshwinK没什么不同。Stream.of(…)不在乎您提供什么元素。您传递`List`元素的事实是无关紧要的。当您无条件地链接`.flatMap(Collection :: stream)`时,它等效于`.flatMap(list list.stream())`,当遇到`null`时,它将失败,就像每次方法调用一样。但是当使用`.flatMap(x-&gt; x == null?null:x.stream())`时,您正在通过将`null`列表映射到`null`流来处理'null'情况,保证`flatMap`像空流一样处理。 (2认同)