javagwtcollectionsguava

How to filter a List by class?


I have a List of super types and want to filter all objects that are of a specific implementation class.

class Base;
class Bar extends Base;
class Foo extends Base;

List<Base> list;

As I use GWT, Guava is only partially supported. Thus I cannot use the following, which would work otherwise in plain java:

Lists.newArrayList(Iterables.filter(list, Bar.class));

How could I replace this for compatibility with GWT?


Solution

  • Iterables#filter(Iterable<?> unfiltered, Class<T> type)
    

    and

    Predicates#instanceOf(Class<?> clazz)
    

    are GWT incompatible, because Class#isInstance(Object obj) is unsupported in GWT, since it it defeats GWT compiler optimizations, and GWT tries to stay away from reflection.

    The instanceof keyword is available, though. So the following would work:

        Iterables.filter(list, new Predicate<Base>() {
            @Override
            public boolean apply(Base input) {
                return input instanceof Bar;
            }
        });
    

    That said, it might just be easier / cleaner to write (see the Guava wiki caveats):

        List<Bar> bars = Lists.newArrayList();
        for (Base base : list) {
            if (base instanceof Bar) {
                bars.add((Bar) base);
            }
        }