Mar*_*rcG 24 java java-stream collectors
它很容易转换List<V>成Map<K, List<V>>.例如:
public Map<Integer, List<String>> getMap(List<String> strings) {
return
strings.stream()
.collect(Collectors.groupingBy(String::length));
}
Run Code Online (Sandbox Code Playgroud)
但我想与自己List和Map 供应商合作.
我想出了这个:
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));
}
Run Code Online (Sandbox Code Playgroud)
问题:是否有更简单,更简洁,更有效的方法?例如,像这样的东西(不起作用):
return strings.stream()
.collect(Collectors.toMap(
String::length,
ArrayList::new,
HashMap::new));
Run Code Online (Sandbox Code Playgroud)
如果我只需要定义List供应商而不是Map供应商,该怎么办?
Tun*_*aki 31
您可以拥有以下内容:
public Map<Integer, List<String>> getMap(List<String> strings) {
return strings.stream().collect(
Collectors.groupingBy(String::length, HashMap::new, Collectors.toCollection(ArrayList::new))
);
}
Run Code Online (Sandbox Code Playgroud)
收集器groupingBy(classifier, mapFactory, downstream)可以用来指定想要哪种类型的地图,通过传递给地图的通缉地图的供应商mapFactory.然后,用于收集分组到相同密钥的元素的下游收集器,其toCollection(collectionFactory)能够收集到从给定供应商获得的集合中.
这可以确保返回的映射是a,HashMap并且每个值中的列表都是ArrayList.请注意,如果要返回地图和集合的特定实现,那么您很可能希望该方法也返回这些特定类型,因此您可以使用它们的属性.
如果您只想指定一个集合供应商,并保留groupingBy默认映射,您可以在上面的代码中省略供应商并使用两个参数重载:
public Map<Integer, List<String>> getMap(List<String> strings) {
return strings.stream().collect(
Collectors.groupingBy(String::length, Collectors.toCollection(ArrayList::new))
);
}
Run Code Online (Sandbox Code Playgroud)
作为旁注,你可以有一个通用的方法:
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))
);
}
Run Code Online (Sandbox Code Playgroud)
这一声明的好处是,你现在可以使用它具有特定HashMap的ArrayListS作为结果,或LinkedHashMap的LinkedListsS,如果主叫方希望它:
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);
Run Code Online (Sandbox Code Playgroud)
但是,在那时,直接使用groupingBy代码可能更简单...
小智 10
如果您打算创建类似于以下内容的地图,则可以使用此解决方案Map<property_1, List<property_2>>:
Map<String, List<String>> ds= requestList.stream().collect(
Collectors.groupingBy(TagRequest::getProperty_1, HashMap::new,
Collectors.mapping(TagRequest::getProperty_2, Collectors.toList()))
);
Run Code Online (Sandbox Code Playgroud)
如果您打算创建类似于 的地图Map<property_1, Set<property_2>>,您可以使用:
Map<String, List<String>> ds= requestList.stream().collect(
Collectors.groupingBy(TagRequest::getProperty_1, HashMap::new,
Collectors.mapping(TagRequest::getProperty_2, Collectors.toSet()))
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16496 次 |
| 最近记录: |