Es ist einfach zu konvertieren List<V>
in Map<K, List<V>>
. Zum Beispiel:
public Map<Integer, List<String>> getMap(List<String> strings) {
return
strings.stream()
.collect(Collectors.groupingBy(String::length));
}
Aber ich will , es zu tun mit meiner eigenen List
und Map
Lieferanten .
Ich habe mit diesem kommen:
public Map<Integer, List<String>> getMap(List<String> strings) {
return strings.stream()
.collect(Collectors.toMap(
String::length,
item -> {List<String> list = new ArrayList<>(); list.add(item); return list;},
(list1, list2) -> {list1.addAll(list2); return list1;},
HashMap::new));
}
Frage: Gibt es eine einfachere, weniger ausführlich, oder effizientere Art und Weise , es zu tun? Zum Beispiel so etwas wie dies (was nicht funktioniert):
return strings.stream()
.collect(Collectors.toMap(
String::length,
ArrayList::new,
HashMap::new));
Und was , wenn ich brauche nur das zu definieren , List
Lieferanten, aber nicht die Map
Lieferanten?
Sie könnten folgende Voraussetzungen erfüllt sein:
public Map<Integer, List<String>> getMap(List<String> strings) {
return strings.stream().collect(
Collectors.groupingBy(String::length, HashMap::new, Collectors.toCollection(ArrayList::new))
);
}
Der Kollektor groupingBy(classifier, mapFactory, downstream)
kann verwendet werden , um festzulegen , welche Art von Karte gesucht, indem sie einen Lieferanten , der das wollte Karte für die Durch mapFactory
. Dann wird der stromabwärtige Sammler, der verwendet wird , um Elemente mit derselben Taste gruppiert zu sammeln ist toCollection(collectionFactory)
, die es ermöglicht , in eine Sammlung von bestimmten Lieferanten erhalten zu sammeln.
Dies stellt sicher , dass die zurückgegebene Karte eine ist HashMap
und dass die Listen, in jedem Wert ist ArrayList
. Beachten Sie, dass , wenn Sie bestimmte Implementierungen von Karte und Sammlung zurückkehren möchten, dann werden Sie wahrscheinlich die Methode wollen auch die spezifischen Typen zurück, so dass Sie ihre Eigenschaften verwenden können.
Wenn Sie nur eine Sammlung Lieferanten angeben möchten, und halten Sie groupingBy
Standard - Karte, können Sie weglassen nur den Lieferanten in dem obigen Code und verwenden die beiden Argumente überlasten :
public Map<Integer, List<String>> getMap(List<String> strings) {
return strings.stream().collect(
Collectors.groupingBy(String::length, Collectors.toCollection(ArrayList::new))
);
}
Als Randbemerkung, könnten Sie eine generische Methode dafür haben:
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))
);
}
Der Vorteil dieser Erklärung ist , dass Sie nun spezifisch haben können HashMap
von ArrayList
s als Ergebnis oder LinkedHashMap
von LinkedLists
s, wenn der Anrufer wünscht es:
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);
aber an diesem Punkt kann es einfacher sein , direkt das zu verwenden , groupingBy
in dem Code ...
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen