so I want to return Set from a entity in database. So I have crudRepository and first I return optional Knight from repo looking by id and then I want to get his set of quests from 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;
}
it almost works but its set of sets and I dont know how can I collet something without making it set? Other question is what if that set of quests is empty, would collect work on null?
Your statement “but its set of sets” suggests that the method getQuests()
returns a Set<Quest>
already.
To flatten nested structures with a Stream
, you’d use 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;
}
But since there is at most one Knight
and hence one Set<Quest>
here, there is no need to go the Stream
route at all. You can simply use
public Set<Quest> getAllUserStories(Long id) {
Optional<Knight> knight = knightRepository.findById(id);
Set<Quest> set = knight.map(Knight::getQuests).orElse(Set.of());
return set;
}
following the general pattern for arbitrary properties, in other words, the fact that this property has a Set
type doesn’t matter. All you need, is a suitable default value for the empty optional. Here, Set.of()
provides an immutable empty set. It’s similar to Collections.emptySet()
, except that it has stricter null
handling, i.e. does even reject query attempts like contains(null)
.
If you’re suspecting that there might be code having problems with such a strict null
handling, you may use Collections.emptySet()
instead.