Collection to stream to a new collection

JavaJava 8Java Stream

Java Problem Overview


I'm looking for the most pain free way to filter a collection. I'm thinking something like

Collection<?> foo = existingCollection.stream().filter( ... ). ...

But I'm not sure how is best to go from the filter, to returning or populating another collection. Most examples seem to be like "and here you can print". Possible there's a constructor, or output method that I'm missing.

Java Solutions


Solution 1 - Java

There’s a reason why most examples avoid storing the result into a Collection. It’s not the recommended way of programming. You already have a Collection, the one providing the source data and collections are of no use on its own. You want to perform certain operations on it so the ideal case is to perform the operation using the stream and skip storing the data in an intermediate Collection. This is what most examples try to suggest.

Of course, there are a lot of existing APIs working with Collections and there always will be. So the Stream API offers different ways to handle the demand for a Collection.

  • Get an unmodifiable List implementation containing all elements (JDK 16):

    List<T> results = l.stream().filter(…).toList();
    
  • Get an arbitrary List implementation holding the result:

    List<T> results = l.stream().filter(…).collect(Collectors.toList());
    
  • Get an unmodifiable List forbidding null like List.of(…) (JDK 10):

    List<T> results = l.stream().filter(…).collect(Collectors.toUnmodifiableList());
    
  • Get an arbitrary Set implementation holding the result:

    Set<T> results = l.stream().filter(…).collect(Collectors.toSet());
    
  • Get a specific Collection:

    ArrayList<T> results =
      l.stream().filter(…).collect(Collectors.toCollection(ArrayList::new));
    
  • Add to an existing Collection:

    l.stream().filter(…).forEach(existing::add);
    
  • Create an array:

    String[] array=l.stream().filter(…).toArray(String[]::new);
    
  • Use the array to create a list with a specific specific behavior (mutable, fixed size):

    List<String> al=Arrays.asList(l.stream().filter(…).toArray(String[]::new));
    
  • Allow a parallel capable stream to add to temporary local lists and join them afterward:

    List<T> results
      = l.stream().filter(…).collect(ArrayList::new, List::add, List::addAll);
    

    (Note: this is closely related to how Collectors.toList() is currently implemented, but that’s an implementation detail, i.e. there is no guarantee that future implementations of the toList() collectors will still return an ArrayList)

Solution 2 - Java

An example from java.util.stream's documentation:

List<String>results =
     stream.filter(s -> pattern.matcher(s).matches())
           .collect(Collectors.toList());

Collectors has a toCollection() method, I'd suggest looking this way.

Solution 3 - Java

As an example that is more in line with Java 8 style of functional programming:

Collection<String> a = Collections.emptyList();
List<String> result = a.stream().
     filter(s -> s.length() > 0).
     collect(Collectors.toList());

Solution 4 - Java

You would possibly want to use toList or toSet or toMap methods from Collectors class.

However to get more control the toCollection method can be used. Here is a simple example:

Collection<String> c1 = new ArrayList<>();
c1.add("aa");
c1.add("ab");
c1.add("ca");

Collection<String> c2 = c1.stream().filter(s -> s.startsWith("a")).collect(Collectors.toCollection(ArrayList::new));

Collection<String> c3 = c1.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());

c2.forEach(System.out::println); // prints-> aa ab
c3.forEach(System.out::println); // prints-> aa ab

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionxenoterracideView Question on Stackoverflow
Solution 1 - JavaHolgerView Answer on Stackoverflow
Solution 2 - JavaSamy DindaneView Answer on Stackoverflow
Solution 3 - JavanobehView Answer on Stackoverflow
Solution 4 - JavaSaikatView Answer on Stackoverflow