Create a neat method out of three similar ones using generics

You can make things a bit shorter with Streams, but I'm not sure there's a way to get around using instanceof here:

public List<PassengerPlane> getPassengerPlanes() {
    return planes.stream().filter(t -> t instanceof PassengerPlane)
                 .map(t -> (PassengerPlane) t).collect(Collectors.toList());
}
public List<MilitaryPlane> getMilitaryPlanes() {
    return planes.stream().filter(t -> t instanceof MilitaryPlane)
                 .map(t -> (MilitaryPlane) t).collect(Collectors.toList());
}
public List<ExperimentalPlane> getExperimentalPlanes() {
    return planes.stream().filter(t -> t instanceof ExperimentalPlane)
                 .map(t -> (ExperimentalPlane) t).collect(Collectors.toList());
}

What do you need is generic method, but the problem is that instanceof cannot check against type parameter (it is in fact erased during compilation), it requires actual class reference. So, you may provide this to the method explicitly:

public <T extends Plane> List<T> getPlanes(Class<T> claz) {
  List<T> result = new ArrayList<>();
  for (Plane plane : planes) {
    if (claz.isInstance(plane)) {
      result.add(claz.cast(plane));
    }
  }
  return result;
}

Note how instanceof and explicit cast changed to calls to .isInstance() and .cast()

Use it like

getPlanes(PassengerPlane.class)

Tags:

Java

Generics