在 Java 选项中加入流中的所有子集

Joining all subsets within a stream in Java optionals

这是原代码:

Set<StatuteType> statuteTypes = registration.getStudent().getStudentStatutesSet()
    .stream()
    .map(StudentStatute_Base::getType)
    .collect(Collectors.toSet());

我想将所有内容包装在一个 Optional 中以避免空指针和所有。如果student不存在或者statutesSet不存在。

我有:

Set<StatuteType> statuteTypes = Optional.of(registration)
            .map(Registration_Base::getStudent)
            .map(student -> student.getStudentStatutesSet())
            .flatMap(Collection::stream)
            .map(StudentStatute_Base::getType)
            .collect(Collectors.toSet())
            .orElse(null);

这样的事情有可能吗?我想避免在此链中进行空值检查,如果有任何空值,也只是 return 一个简单的空值,而不是得到一个异常。

通常我认为合乎逻辑的是使用 flatMap as described here 但在这种情况下似乎不正确,因为可选平面图 return 是可选的。

Collection::stream 不是 return 而是 Optional,所以你不应该在这里使用 flatMap。您应该继续使用可选的 map

.map(Collection::stream) 给你一个 Optional<Stream<Statute>>。您似乎正在尝试调用 stream 的 mapcollect 方法。但是你需要先调用 Optional.map 才能这样做。

如果 registration 可以为 null,您还应该使用 Optional.ofNullable

Set<StatuteType> statuteTypes = Optional.ofNullable(registration)
    .map(Registration_Base::getStudent)
    .map(student -> student.getStudentStatutesSet())
    .map(Collection::stream)
    .map(x -> // Optional.map
        x.map(StudentStatute_Base::getType) // Stream.map
            .filter(Objects::nonNull) // I assume you want to filter out the statute types which are null?
            .collect(Collectors.toSet())
    )
    .orElse(null);

这是一个简单的方法:

Set<StatuteType> statuteTypes = Optional.ofNullable(registration)
    .map(Registration_Base::getStudent)
    .map(student -> student.getStudentStatutesSet())
    .map(Collection::stream)
    .orElseGet(Stream::empty)    // Exit Optional, enter stream
    .map(StudentStatute_Base::getType)
    .collect(Collectors.toSet());

但是,它不会导致空集。集合永远不应该为 null,只能是空的。我会推荐这种方法。使用 Optional 对象的全部意义在于,您永远不必处理空值。