Here is the example of code that I struggle with:
List<CategoryHolder> categories = ...
List<String> categoryNames = categoryIds.stream()
.map(id -> categories.stream()
.filter(category -> category.getId().equals(id))
.findFirst().get().getName())
.collect(Collectors.toList());
So I have a list of CategoryHolder
objects consisting of category.id
and category.name
. I also have a list of category ids. I want to iterate through ids and for each id I want to iterate through the CategoryHolder
list and when id
from categoryIds
list is matched with a CategoryHolder.id
I want to return the category.name
. So basically I want to map every value from categoryIds
to its category.name
.
So the problem is when no values are matched, filter doesn't pass any elements through and there is nothing to collect, so I would like to break from the current inner stream, and continue to the next id from categoryIds
list. Is there a way to achieve this in stream API?
You can do like:
categories.stream()
.filter(categoryHolder -> categoryIds.stream()
.anyMatch(id->categoryHolder.getId().equals(id)))
.map(CategoryHolder::getName)
.collect(Collectors.toList());
or for better performance you can do:
Map<String,CategoryHolder> map = categories.stream()
.collect(Collectors.toMap(CategoryHolder::getId, Function.identity()));
List<String> names = categoryIds.stream()
.map(id -> map.get(id).getName())
.collect(Collectors.toList());
The problem is with your call to filter where you are doing .findFirst().get().getName()
This would fail in case empty Optional is returned by findFirst()
.
You can instead rewrite it as follows:
List<String> categoryNames =
categoryIds
.stream()
.map(id -> categories
.stream()
.filter(catgory -> catgory.getId().equals(id))
.findFirst())
.collect(
ArrayList::new,
(list, optional) -> {
optional.ifPresent(categoryHolder -> list.add(categoryHolder.name));
},
(list, list2) -> {}
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.