【问题标题】:Returning set from Optional从可选返回集
【发布时间】:2021-10-20 16:31:20
【问题描述】:
所以我想从数据库中的实体返回 Set。所以我有 crudRepository ,首先我从 repo 中返回可选的 Knight,通过 id 查找,然后我想从 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;
}
它几乎可以工作,但是它的集合,我不知道如何在不设置的情况下收集一些东西?
另一个问题是,如果那组任务是空的,会在 null 上收集工作吗?
【问题讨论】:
标签:
java
jpa
java-stream
optional
【解决方案1】:
您的陈述“但它的集合”表明方法 getQuests() 已经返回 Set<Quest>。
要使用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;
}
但是由于这里最多只有一个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;
}
遵循任意属性的一般模式,换句话说,该属性具有Set 类型这一事实并不重要。您只需要一个适合空选项的默认值。这里,Set.of() 提供了一个不可变的空集。它类似于Collections.emptySet(),除了它有更严格的null 处理,即甚至拒绝像contains(null) 这样的查询尝试。
如果您怀疑代码在使用如此严格的null 处理时可能存在问题,您可以改用Collections.emptySet()。
【解决方案2】:
public Set<Quest> getAllUserStories(Long id){
//Assuming Knight is a List or Set
Optional<Knight> knightOptional = knightRepository.findById(id);
//check here if value is present in the optional or not
Knight knight = knightOptional.isPresent() ? knightOptional.get() : null;
if(knight != null){
return knight.stream().map(k->k.getQuests()).collect(Collectors.toSet());
}
return new HashSet<Quest>();
}