Passing from list <a> to list <b> when B expands A
I have two clans:
public class A {
//attibutes and methods
}
public class B extends A {
//atributes and methods
}
Now I have a service that returns a list of elements of type A . Let's call it generateAElements () ;
I want to call this method , filter the list obtained only to keep elements of type B that are also of type A.
List<A> listA = generateAElements();
List<A> listAA = listA.filter( p -> p instanceof B).collect(Collectors.toList());
List<B> listB = new ArrayList<>();
// need to create a new list, iterate overListA and add elements of type B?
for (A itemA : listA) {
listB.add((B) itemA);
}
Is there an efficient way to do this?
Important: the list can contain a large number of items.
source to share
Assuming you are using Java 8+ you can use streams:
List<B> listB = listA
.stream()
.filter(B.class::isInstance)
.map(B.class::cast)
.collect(Collectors.toList());
Of course this can be done in earlier versions of Java, it will likely be more verbose.
A note on terminology: This is not a "casting from List<A>
to List<B>
" - the only things that are done here are individual entries.
source to share
Streaming version. You just need to do a compatibility check before casting and you can do whatever you want.
List<A> listA = generateAElements();
List<B> listB = new LinkedList<>();
for (A item : listA) {
// Skip non compatable items
if(item instanceof B)
listB.add((B) item);
}
The key difference from the OP's code is the line if(item instanceof B)
that does the OP's filtering / error checking, but doesn't. (This is technically the same as what the streamed version does, but a little more verbose and much less overhead)
source to share