Given a collection c
with elements of type T
(or T
's subtypes) return some element e
of type R
from c
so that R
is a subtype of T
.
Motivation: I want to use specific methods of R
on e
.
UPDATE: From the aioobe's answer added to the requirements acceptance of R
's subtypes for e
.
Here is my working implementation:
import java.util.ArrayList;
import java.util.List;
public class ReturnSpecificTypeFromGeneric {
public static <T, R extends T> R findFirstElementOfType(
List<? extends T> elements,
Class<R> requiredClass
) {
for (T element : elements) {
if (requiredClass.isAssignableFrom(element.getClass())) {
// WARNING: Unchecked cast: 'T' to 'R'
//noinspection unchecked
return (R) element; // [1]
}
}
return null;
}
public static void main(String[] args) {
List<Mammal> mammals = new ArrayList<>();
mammals.add(new Elephant());
mammals.add(new WhiteRhino());
mammals.add(new Rhino());
Rhino rhino = findFirstElementOfType(mammals, Rhino.class);
System.out.println(rhino.getClass()); // returns: class WhiteRhino
}
}
class Mammal {}
class Elephant extends Mammal {}
class Rhino extends Mammal {}
class WhiteRhino extends Rhino {}
Questions:
- Is this a right approach?
- Can the unchecked cast (marked as
[1]
) be avoided, and how, and should it be cared about? - Other solutions if possible.
That code looks reasonable to me.
You could "hide" the cast by instead using
requiredClass.cast(element)
.Basically the same solution, but you could express it using streams as follows:
or
.orElse(null)
in the end, if you want the exact behavior of your original snippet.