Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot return Stream of subclass objects after filtering

I have a method that returns a Stream of type A. I also have a subtype B of A. The method creates a Stream that it populates with instances of B, which are also of type A due to inheritance. This works fine, until I introduce a filter on the Stream. Then, the compiler decides that the Stream is of type B and not A, and inheritance does not seem to matter. Why does this happen?

Here is a minimal reproducible example:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Main {

    abstract class A {
        int member;
    }

    class B extends A {

        public B(int member) {
            this.member = member;
        }
    }

    public static void main(String[] args) {
        Stream<A> stream = getStream();
    }

    private Stream<A> getStream() {
        List<Integer> ints = new ArrayList<>();
        ints.add(1);
        ints.add(2);
        ints.add(3);

        return ints.stream().map(B::new).filter(b -> true); // Filter causes compiler to throw error
    }

}
like image 365
Sahand Avatar asked Jun 14 '26 04:06

Sahand


1 Answers

Thank you Holger, for setting the record straight. This is a case of type inference of generics types not having been expanded to chained invocation because of the added complexity it would bring. So as soon as you chain the filter() call, the inference mechanism can't determine the type automatically anymore.

You don't need to cast with an additional clumsy .map(A.class::cast), modify the return type to Stream<? extends A> or do anything else except specify the generic type in the map() call

return ints.stream().<A>map(B::new).filter(b -> true);
like image 170
Kayaman Avatar answered Jun 17 '26 20:06

Kayaman