Ответ 1
У вас может быть следующее:
public Map<Integer, List<String>> getMap(List<String> strings) {
return strings.stream().collect(
Collectors.groupingBy(String::length, HashMap::new, Collectors.toCollection(ArrayList::new))
);
}
Коллектор groupingBy(classifier, mapFactory, downstream)
может использоваться для указания того, какой тип карты требуется, передав ему поставщика желаемой карты для mapFactory
. Затем сборщик нисходящего потока, который используется для сбора элементов, сгруппированных по одному и тому же ключу, toCollection(collectionFactory)
, который позволяет собирать в полученную коллекцию от данного поставщика.
Это гарантирует, что возвращаемая карта является HashMap
и что списки в каждом значении ArrayList
. Обратите внимание: если вы хотите вернуть конкретные реализации карты и коллекции, то вы, скорее всего, хотите, чтобы метод возвращал эти конкретные типы, поэтому вы можете использовать их свойства.
Если вы хотите указать поставщика коллекции и сохранить карту groupingBy
по умолчанию, вы можете просто опустить поставщика в приведенном выше коде и использовать two перегрузка аргументов:
public Map<Integer, List<String>> getMap(List<String> strings) {
return strings.stream().collect(
Collectors.groupingBy(String::length, Collectors.toCollection(ArrayList::new))
);
}
В качестве побочной заметки для этого может быть общий метод:
public <K, V, C extends Collection<V>, M extends Map<K, C>> M getMap(List<V> list,
Function<? super V, ? extends K> classifier, Supplier<M> mapSupplier, Supplier<C> collectionSupplier) {
return list.stream().collect(
Collectors.groupingBy(classifier, mapSupplier, Collectors.toCollection(collectionSupplier))
);
}
Преимущество этого объявления состоит в том, что теперь вы можете использовать его для получения определенного HashMap
of ArrayList
в качестве результата или LinkedHashMap
of LinkedLists
s, если вызывающий абонент пожелает его:
HashMap<Integer, ArrayList<String>> m = getMap(Arrays.asList("foo", "bar", "toto"),
String::length, HashMap::new, ArrayList::new);
LinkedHashMap<Integer, LinkedList<String>> m2 = getMap(Arrays.asList("foo", "bar", "toto"),
String::length, LinkedHashMap::new, LinkedList::new);
но в этот момент может быть проще непосредственно использовать groupingBy
в коде...