Java 8 List Management

I'm trying to do some basic card / filter operations on a list in a method ListChangeListener.onChanged(Change<? extends Place>)

and I can get it to work using the old fashioned "iterate and do some action" method, but I wanted to try and write it using a method stream()

from java 8. The commented part does not give same result, but doesn't allow for filtering categories correctly (and yes, I have a working implementation equals(Object)

forCategory

for (Place p : change.getAddedSubList()) {
    if (!categories.contains(p.getCategory())) {
        categories.add(p.getCategory());
    }
}
// List<Category> addedCategories = change.getAddedSubList().stream()
// γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€.map(Place::getCategory)
//γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€γ€€.filter((c) -> { return !categories.contains(c); })
//  γ€€                                    .collect(Collectors.toList());
//γ€€categories.addAll(addedCategories);

      

+3


source to share


2 answers


This is because in the first version, once you add a category to the list, the subsequent occurrence of that category is not added a second time: you have already added it to the list. The second version doesn't do the same. Therefore, you need to make sure the categories are unique in the stream:

change.getAddedSubList().stream()
      .map(Place::getCategory)
      .distinct()
      .filter(c -> !categories.contains(c))
      .forEachOrdered(c ->γ€€categories.add(c));

      



Note that you also do not need to compile into a temporary list.

+4


source


Duplicates in your stream can lead to duplications in the category list if they are not already in the category list beforehand, since the filter method is applied to all items before one of them is inserted.



One solution would be to insert the call into .distinct()

your thread, another way to collect through Collectors.toSet()

.

+2


source







All Articles