I would like to create a Java stream that will collect only elements that are instanceof
class A
and at the same time are distinct by x
.
I am using Java 8.
What I have in the beginning is a List
of instances of class C
.
Class A extends B{
int x;
}
Class B extends C{
}
Class C(){
}
but other classes also extend class C.
What I did so far:
List<C> input = ...;
List<C> result = input.stream()
.filter(r -> r instanceof A)
.collect(Collectors.toList());
And this works fine however for the first part.
However, I would like to compare all elements and get a List
of distinct objects (compare by value of int x
).
You can define a method that would expect an instance of target class Class<T>
in order to filter out any subtype of C
from the source list.
Note that would work only if equals/hashCode
contract was properly implemented by each subclass.
public static <T extends C> List<T> getItemsOfType(List<C> source,
Class<T> itemClass) {
return source.stream()
.filter(item -> itemClass.isAssignableFrom(item.getClass())) // ensures that this element can be safely casted to the target type
.map(itemClass::cast) // casting to the type T
.distinct() // ensures uniqueness of elements according to `equals/hashCode` implementation of the type T
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<C> input = List.of(new A(1), new D(), new A(3));
List<A> result = getItemsOfType(input, A.class);
System.out.println(result);
}
Output:
[A{x=1}, A{x=3}]