obfuscation
obfuscation

Reputation: 1043

Split a Set into multiple Sets by Class

Apologies if this has been answered elsewhere, but I have yet to find a good answer!


I have a Set of objects that I need to split by their underlying class type, into a Set for each (obviously this means that each object in the initial set will only appear in one of the new Set objects).

My current approach to this is as follows:

public static Map<Class,Set<Foo>> splitByClass(Set<Foo> foos) {

    // Create a map for the result
    Map<Class,Set<Foo>> FooMap = new HashMap<Class,Set<Foo>>();

    for (Foo foo: foos) {
        Class type = foo.getClass();

        // If a set for this key exists, add the item to that.
        if (FooMap.containsKey(type)) {
            FooMap.get(type).add(foo);
        } else {
            // Otherwise make a new set, add the item and the set to the map.
            Set<Foo> set = new HashSet<Foo>();
            set.add(foo);
            FooMap.put(type, set);
        }
    }        
    return FooMap;
}

My question: Is there a more generic way to split a Set into subsets, based on some evaluation method such as checking Class type?

Upvotes: 2

Views: 1824

Answers (1)

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 299048

You can use a Guava Multimap, it will make life a lot simpler:

Multimap<Class<? extends Foo>, Foo> mmap = HashMultimap.create();
for (Foo foo : foos) {
    mmap.put(foo.getClass(), foo);
}
return mmap;

This code is pretty much equivalent to your above code, except that you must change the return type to Multimap<Class<? extends Foo>, Foo>.

And here's a generic version that works with any supplied interface type:

public static <X> Multimap<Class<X>, X> splitByClass(
    final Iterable<? extends X> implementations, final Class<X> interfaceType) {

    final Multimap<Class<X>, X> mmap = HashMultimap.create();
    for (final X implementation : implementations) {
        @SuppressWarnings("unchecked")
        // this should be safe:
        final Class<X> implementationType = (Class<X>) implementation.getClass();
        mmap.put(implementationType, implementation);
    }
    return mmap;
}

Upvotes: 2

Related Questions