If you are looking for a library, my first thought was to use Google Guava Libraries as follows:
public <T, U extends T> List<U> homogenize(List<T> list, final Class<U> subclass) { Predicate<T> pred = new Predicate<T>() { @Override public boolean apply(T input) { return input.getClass().isAssignableFrom(subclass); } }; return Iterables.all(list, pred) ? (List<U>)list : null; }
I have not tried to make sure that there are no kinks. However, I looked at him and decided that he was pretty butt-ugly. Guwa's approach is slightly better:
public <T, U extends T> List<U> homogenize(List<T> list, Class<U> subclass) { Iterable<U> ret = Iterables.filter(list, subclass); if (list.size() != Lists.newArrayList(ret).size()) return null; return (List<U>)list; }
However, it is still a little ugly. And he uses an internal copy of the collection. It still returns the cast look of the original. After all, everything has been said and done, the cleanest approach seems to use ordinary Java:
public <T, U extends T> List<U> homogenize(List<T> list, Class<U> subclass) { for( T t : list) { if (!t.getClass().isAssignableFrom(subclass)) return null; } return (List<U>)list; }
Depending on your aversion to style warnings, you can even opt out of broadcast operators in all three options.
EDIT ON COMMENTS The following changes / improvements were proposed in the comments.
Option one is improved:
public <T, U extends T> List<U> homogenize(List<T> list, final Class<U> subclass) { return Iterables.all(list, Predicates.instanceOf(subclass)) ? (List<U>)list : null; }
Improved second option:
public <T, U extends T> List<U> homogenize(List<T> list, Class<U> subclass) { Iterable<U> ret = Iterables.filter(list, subclass); return (list.size() != Iterables.size(ret)) ? null : (List<U>)list; }
Option three is improved:
public <T, U extends T> List<U> homogenize(List<T> list, Class<U> subclass) { for( T t : list) { if (!subclass.isInstance(t.getClass())) return null; } return (List<U>)list; }
With these improvements, the first Guava example shines quite a bit. If you don't mind static imports, both Guava examples become extremely readable.