Here is a solution using a reusable Gatherer per the JEP 485: Stream Gatherers Java 24 language feature (available as a preview language feature since Java 22)
Gatherer<Object, Void, Integer> cast = Gatherer.of(Integrator.ofGreedy((state, element, downstream) -> { if (element instanceof Integer i) { return downstream.push(i); } else { return true; } })); // Returns [1, 2, 4, 5, 10] List<Integer> integers = Stream.of(1, 2, 3.0, 4, 5, 6.0, true, 8L, "nine", 10) .gather(cast) .toList();
Or, the same thing but behind a generic method to cast to a requested type:
static <T> Gatherer<Object, ?, T> casting(Class<T> clazz) { return Gatherer.of(Integrator.ofGreedy((state, element, downstream) -> { if (clazz.isInstance(element)) { return downstream.push(clazz.cast(element)); } else { return true; } })); } // ... // Returns [1, 2, 4, 5, 10] List<Integer> integers = Stream.of(1, 2, 3.0, 4, 5, 6.0, true, 8L, "nine", 10) .gather(casting(Integer.class)) .toList();
This custom gatherer casts and keeps all elements of the given type, and skips any elements that aren't of that type.
Javadocs
Gatherer:
An intermediate operation that transforms a stream of input elements into a stream of output elements, optionally applying a final action when the end of the upstream is reached. […]
[…]
There are many examples of gathering operations, including but not limited to: grouping elements into batches (windowing functions); de-duplicating consecutively similar elements; incremental accumulation functions (prefix scan); incremental reordering functions, etc. The class Gatherers provides implementations of common gathering operations.
API Note:
A Gatherer is specified by four functions that work together to process input elements, optionally using intermediate state, and optionally perform a final action at the end of input. They are:
Stream.gather(Gatherer<? super T,?,R> gatherer):
Returns a stream consisting of the results of applying the given gatherer to the elements of this stream.
Gatherer.of(Gatherer.Integrator<Void,T,R> integrator)
Returns a new, parallelizable, and stateless Gatherer described by the given integrator.