将Java的Optional中流中的所有子集连接起来

huangapple go评论73阅读模式
英文:

Joining all subsets within a stream in Java optionals

问题

这是原始的代码片段:

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

我想将所有内容包装在一个Optional中,以避免空指针等问题。如果学生不存在或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);

类似这样的方式是否可行?我想在这个链式操作中避免空检查,如果有任何空值,只需返回一个简单的null,而不是得到异常。

通常我认为在这种情况下使用flatMap(如此处所述)是合乎逻辑的,但似乎不正确,因为Optional的flatMap返回一个Optional。

英文:

This is the original piece of code:

Set&lt;StatuteType&gt; statuteTypes = registration.getStudent().getStudentStatutesSet()
    .stream()
    .map(StudentStatute_Base::getType)
    .collect(Collectors.toSet());

I want to wrap everything in an Optional to avoid null pointers and all. If the student does not exist or the statutesSet does not exist.

What I have:

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

Would something like this be in someway possible? I want to avoid null checks in this chain, and if there's any null just return a simple null as well instead getting an exception.

Normally what I think would be logical would be to use a flatMap as described here but it doesn't seem to be correct in this case, because the Optional flatmap returns an Optional.

答案1

得分: 5

这里有一个简单的方法来实现:

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

然而,这并不会导致一个空集合。集合永远不应为 null,只能是空集合。我会推荐使用这种方法。使用 Optional 对象的整个目的是为了不必处理 null 值。

英文:

Here's a simple way of doing it:

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

However, it does not result in a null set. Collections should never be null, only empty. I would recommend this approach. The whole point of using an Optional object is so you never have to deal with null values.

答案2

得分: 3

Collection::stream不会返回Optional,因此在这里不应该使用flatMap。您应该继续在可选项上使用map

.map(Collection::stream)会给您一个Optional&lt;Stream&lt;Statute&gt;&gt;。您似乎试图在此上调用_stream_的mapcollect方法。但在此之前,您需要首先调用Optional.map

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

Set&lt;StatuteType&gt; statuteTypes = Optional.ofNullable(registration)
    .map(Registration_Base::getStudent)
    .map(student -&gt; student.getStudentStatutesSet())
    .map(Collection::stream)
    .map(x -&gt; // Optional.map
        x.map(StudentStatute_Base::getType) // Stream.map
            .filter(Objects::nonNull) // 我假设您想要过滤掉为null的法规类型?
            .collect(Collectors.toSet())
    )
    .orElse(null);
英文:

Collection::stream does not return an Optional, so you should not use flatMap here. You should keep using map on the optional.

.map(Collection::stream) gives you an Optional&lt;Stream&lt;Statute&gt;&gt;. You seem to be trying to call the stream's map and collect methods on this. But you need to first call Optional.map before you can do that.

You should also use Optional.ofNullable if registration could be null:

Set&lt;StatuteType&gt; statuteTypes = Optional.ofNullable(registration)
    .map(Registration_Base::getStudent)
    .map(student -&gt; student.getStudentStatutesSet())
    .map(Collection::stream)
    .map(x -&gt; // 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);

huangapple
  • 本文由 发表于 2020年9月22日 20:55:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/64010190.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定