从 Optional 返回集合

tho*_*413 1 java jpa optional java-stream

所以我想从数据库中的实体返回 Set 。所以我有 crudRepository,首先我通过 id 从 repo 中返回可选的 Knight,然后我想从 Optionlal 获取他的一组任务

public Set<Quest> getAllUserStories(Long id)
    {
        Optional<Knight> knight = knightRepository.findById(id);
       Set<Quest>set = knight.stream().map(k->k.getQuests()).collect(Collectors.toSet());


        return listToReturn;
    }

Run Code Online (Sandbox Code Playgroud)

它几乎可以工作,但它的一套,我不知道如何在不设置的情况下夹住一些东西?另一个问题是,如果那组任务是空的,会在 null 上收集工作吗?

Hol*_*ger 5

你的陈述“but its set of sets”表明该方法已经getQuests()返回 a Set<Quest>

要使用 a 展平嵌套结构Stream,您可以使用flatMap

public Set<Quest> getAllUserStories(Long id) {
    Optional<Knight> knight = knightRepository.findById(id);
    Set<Quest> set = knight.stream()
        .flatMap(k -> k.getQuests().stream())
        .collect(Collectors.toSet());
    return set;
}
Run Code Online (Sandbox Code Playgroud)

但既然这里最多只有一个Knight,也就一个Set<Quest>,所以根本没有必要走这Stream条路。你可以简单地使用

public Set<Quest> getAllUserStories(Long id) {
    Optional<Knight> knight = knightRepository.findById(id);
    Set<Quest> set = knight.map(Knight::getQuests).orElse(Set.of());
    return set;
}
Run Code Online (Sandbox Code Playgroud)

遵循任意属性的一般模式,换句话说,该属性是否具有Set类型这一事实无关紧要。您只需要一个合适的默认值作为空的可选项。在这里,Set.of()提供了一个不可变的空集。它类似于Collections.emptySet(),除了它有更严格的null处理,即甚至拒绝像 那样的查询尝试contains(null)

如果您怀疑这样严格null处理可能存在代码问题,您可以Collections.emptySet()改用。