Collection to stream to a new collection
java, java-8, java-stream
Solution
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 `Collection`s 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`)
Problem
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.