Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve "add all in list cannot be applied to"

I have this method:

filteredListIn.addAll(Stream.of(listRef)
    .filter(results ->
            results.getTitle().contains(query.toString().toLowerCase())
     ));

With these two variables:

private List<Results> listRef = new ArrayList<>();
List<Results> filteredListIn = new ArrayList<>();

But I'm getting

found for addAll(Stream) filteredListIn.addAll(Stream.of(listRef) ^ method Collection.addAll(Collection) is not applicable (argument mismatch; Stream cannot be converted to Collection) method List.addAll(Collection) is not applicable

What is the problem and how can I solve this?

Is it possible it's happening because I use external library for supporting streams under api 24?

like image 634
Jonny Avatar asked May 25 '20 09:05

Jonny


People also ask

How do you use add all in Arraylist?

Example 3: Inserting Elements from Set to ArrayList addAll(set); Here, we have used the addAll() method to add all the elements of the hashset to the arraylist. The optional index parameter is not present in the method. Hence, all elements are added at the end of the arraylist.

How does list add work?

There are two methods to add elements to the list. add(E e): appends the element at the end of the list. Since List supports Generics, the type of elements that can be added is determined when the list is created. add(int index, E element): inserts the element at the given index.


3 Answers

addAll expects a Collection parameter. As long as a stream is not collected, it is of type Stream which is independent of Collection. Other answers give you a simple solution: collect to a list, then add this list.

I want to mention though that this is not the most efficient solution and introduces quite some memory overhead: the stream is first collected to a new list, then all items of this list are copied to your existing list, and eventually the garbage collector will free the occupied space of the temporary list.

This overhead (allocating memory for the backing array of the temporary list) can be avoided by not collecting the stream, but iterating over its elements with the forEach terminal operation:

Stream.of(listRef)
        .filter(results -> results.getTitle().contains(query.toString().toLowerCase()))
        .forEach(filteredListIn::add);

If your list is empty to begin with, the best solution is to collect it directly:

final List<...> filteredListIn = Stream.of(listRef)
        .filter(results -> results.getTitle().contains(query.toString().toLowerCase()))
        .collect(Collectors.toList()); // or .toUnmodifiableList
like image 186
knittl Avatar answered Oct 22 '22 04:10

knittl


You have to collect all stream elements in a list in order to add it to a collection:

filteredListIn.addAll(listRef.stream()
  .filter(results -> results.getTitle().contains(query.toString().toLowerCase()))
  .collect(Collectors.toList());
like image 25
Titulum Avatar answered Oct 22 '22 05:10

Titulum


FYI Stream.of(listRef) will give back List<Results> and there is no method .getTitle() on List. I think you mean to do listRef.stream().filter... instead of Stream.of(listRef).filter...

Anyways, this is a standard example which demonstrates that you shouldn't use streams for every operation. You can reduce the streams to:

listRef.removeIf(results -> !results.getTitle().contains(query.toString().toLowerCase()));
filteredListIn.addAll(listRef);

Note: .removeIf will effectively operate on listRef so you should clone if required.

like image 7
Aniket Sahrawat Avatar answered Oct 22 '22 04:10

Aniket Sahrawat