Разделить набор на несколько наборов по классу - PullRequest
2 голосов
/ 21 сентября 2011

Извините, если на этот вопрос уже был дан ответ, но я еще не нашел хорошего ответа!


У меня есть Set объектов, которые мне нужно разделить по их базовому типу class на Set для каждого (очевидно, это означает, что каждый объект в исходном наборе будет отображаться только в один новых Set объектов).

Мой текущий подход к этому таков:

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;
}

Мой вопрос: Существует ли более общий способ разбиения Set на подмножества, основанный на некотором методе оценки, например проверке типа класса?

1 Ответ

2 голосов
/ 21 сентября 2011

Вы можете использовать Guava Multimap, это сделает жизнь намного проще:

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

Этот код в значительной степени эквивалентен приведенному выше коду, за исключением того, что вы должныизмените тип возвращаемого значения на Multimap<Class<? extends Foo>, Foo>.

А вот общая версия, которая работает с любым предоставленным типом интерфейса:

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;
}
...