0

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!

3
  • 3
    Streams are not designed to modify collections. What end result are you looking for? Commented Dec 25, 2019 at 3:48
  • What would a Category class look like? It seems to me that would best be served by an enum and using an EnumSet instead of a List<Category>. Commented Dec 25, 2019 at 3:53
  • A list of food objects containing only food objects whose categories are not inside the excludedCategories List Commented Dec 25, 2019 at 13:34

4 Answers 4

5

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));

Collections::disjoint

Collections::removeIf

Sign up to request clarification or add additional context in comments.

2 Comments

Your first approach will only contain categories as a list I believe. Not the filtered Food list
@SunilDabburi You are correct! It will return a List<Category> , not a List<Food>
1

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());

Comments

0

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);

2 Comments

What is getCats?
getCategories is getter method for fecthing category list.
0
foodList.removeIf(f -> f.getCategories().stream().anyMatch(excludeCategories::contains));

you can use removeIf and anyMatch to achieve the desired result

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.