Reputation: 416
I have a list named "foodList" which contains elements of type "Food". The object Food contains a List named "categories" of type "Category".
I am currently implementing a search algorithm to filter food by excluding certain categories.
Excluded Categories are stored inside a List named "excludedCategories".
How can I, using Java 8 and streams, filter the foodList by excluding Food objects whose categoryLists contain any element of the excludedCategories list?
Sample code with loops:
for (Food f: foodList)
{
for (Category c: f.categories)
{
if (excludedCategories.contains(c))
{
// REMOVE ITEM FROM foodList
}
}
}
Thank you!
Upvotes: 0
Views: 6018
Reputation: 556
foodList.removeIf(f -> f.getCategories().stream().anyMatch(excludeCategories::contains));
you can use removeIf and anyMatch to achieve the desired result
Upvotes: 0
Reputation: 500
you can do like this
foodList.stream().filter(f -> {
f.setCats(f.getCats().stream().filter(c -> (!excludedCategories.contains(c))).collect(Collectors.toList()));
return true;
}).collect(Collectors.toList()).forEach(System.out::println);
Upvotes: 0
Reputation: 1472
Use the stream
to filter
the excluded
categories as following
foodList.stream()
.filter(f -> f.categories.stream().noneMatch(c -> excludedCategories.contains(c)))
.collect(Collectors.toList());
Upvotes: 1
Reputation: 12819
Streams shouldn't be used to modify the List
. Instead you should return a new List
with only the appropriate elements in it. You could simply flip the logic a little and use filter:
foodList.stream().flatMap(e -> e.categories.stream())
.filter(c -> !excludedCategories.contains(c))
.collect(Collectors.toList());
However it would be much simpler to use the built in methods:
foodList.removeIf(e -> !Collections.disjoint(e.categories, excludedCategories));
Upvotes: 5