轻松转换List<V>
成Map<K, List<V>>
。例如:
public Map<Integer, List<String>> getMap(List<String> strings) {
return
strings.stream()
.collect(Collectors.groupingBy(String::length));
}
但是我想和我自己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));
}
问题: 是否有一种更简单,更省时或更有效的方法?例如,像这样的东西(不起作用):
return strings.stream()
.collect(Collectors.toMap(
String::length,
ArrayList::new,
HashMap::new));
如果我只需要定义List
供应商,而不是Map
供应商,该怎么办?
您可能具有以下内容:
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
。请注意,如果要返回map和collection的特定实现,则很可能希望该方法也返回这些特定类型,因此可以使用其属性。
如果您只想指定集合供应商并保留groupingBy
默认地图,则可以在上面的代码中省略供应商,并使用两个参数重载:
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
的ArrayList
S作为结果,或LinkedHashMap
的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
在代码中使用可能会更简单…
我正在尝试创建一个简单的解析util,它转换一个两列CSV文件并将其放入一个映射。 如您所见,我正在创建一个字符串流,用逗号分隔每一行,并将其转换为字符串数组,最后将键映射到索引0,将值映射到索引1。 出于某种原因,当我运行这个测试时,实际值为null。我排除了无效的文件路径,因为它在另一个单元测试中运行良好,并且键值出现在CSV中。我已经盯着它看了几个小时了,我想也许有人能指出我的错误。 此外,
我有一个任务:返回一个公司地图,其中键是它的名称,值是存储为String的员工列表,由和组成,用空格分隔。这是我的解决方案和它的工作罚款: 所以我的问题是,如何转换
谁能给我解释一下为什么下面的代码不起作用? 我试图了解Java8的新特性,并解决了BerlinClock卡塔问题。在此期间,我必须以的格式解析字符串--我想使用流,并编写了下面的代码。 但是运行时系统(我认为)抱怨无法执行显式类型转换。
我想得到以下数据结构:Map 给定的是一个包含字段als原语(位置、目标、距离)或作为键(位置)加映射(目标)的类。从每个独特的位置,一个人可以瞄准多个目的地(按距离)。 关于第二个代码段:结果应该与第一个代码中的结果相同。唯一的区别是,LocationPair中提供的数据已被进一步处理,因此目的地和距离已被放入其目标地图中。 我知道这一定是可能的,但不知何故,我无法弄清楚如何完成它。上面的流代码
问题内容: 我需要将Java转换为的实例(包括地图内容) 我应该怎么做才能使此代码可编译? 问题答案: 从Collectors.toMap(…)javadoc: 例如:
问题内容: 我有一个清单 我想将其转换为 我试过了 但是Java对以下内容不满意: 感谢帮助 问题答案: 的第二个参数期望a 将项目转换为将被放置在地图中的值。但是,您提供了,而不是。 看起来您想为每个项目都添加一个空列表,因此请更改 至 但是,返回一个 不可变的 空列表,这可能不是您想要的。 返回一个空列表(不可变)。该列表是可序列化的。 你可能想要