我一直在尝试使用collect method of Stream,将列表转换为HashMap。 我使用下面的代码作为参考:
String result = list.parallelStream().collect(StringBuilder::new,
(response, element) -> response.append(" ").append(element),
(response1, response2) -> response1.append(",").append(response2.toString()))
.toString();
当我在eclipse中写下面不完整的语句并在 ctrl + 空间处?
Map<String,Choice> map1= list1.stream().collect(()-> new HashMap<String,Choice>(),
(r,s) -> r.?,(r,s) -> r.putAll(s));
考虑到使用StringBuilder的代码片段,我的期望是,累加器函数的第一个参数应该是HashMap,因为我使用了HashMap :: new作为供应商函数。根据这种理解,eclipse应该建议我使用HashMap的方法,但事实并非如此。
然而,这似乎工作正常
list1.stream().collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
已经提到Java 8 Int Stream collect with StringBuilder但是,运气不好。
答案 0 :(得分:2)
将列表转换为地图?
Collectors.toMap(..)
可能就是您所需要的。
javadocs有几个很好的例子:https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap-java.util.function.Function-java.util.function.Function-
答案 1 :(得分:2)
如果你想探索更多的supplier, accumulator, combiner
,你应该写一下,开始时要清楚一点。
假设你有一个这样的类:
static class Foo {
private final int id;
private final String s;
public Foo(int id, String s) {
super();
this.id = id;
this.s = s;
}
public int getId() {
return id;
}
public String getS() {
return s;
}
@Override
public String toString() {
return "" + id;
}
}
如果您知道,在这种情况下s
将是唯一的,您只需执行此操作:
HashMap<String, Foo> result = Arrays.asList(new Foo(1, "a"), new Foo(2, "b"))
.stream()
.collect(HashMap::new,
(map, foo) -> map.put(foo.getS(), foo),
HashMap::putAll);
System.out.println(result); // {a=1, b=2}
但如果s
不唯一,您可能需要收集到List
,这会使事情变得更复杂:
HashMap<String, List<Foo>> result = Arrays.asList(
new Foo(1, "a"),
new Foo(2, "b"),
new Foo(3, "a"))
.stream()
.parallel()
.collect(HashMap::new,
(map, foo) -> {
map.computeIfAbsent(foo.getS(), s -> new ArrayList<>()).add(foo);
},
(left, right) -> {
for (HashMap.Entry<String, List<Foo>> e : right.entrySet()) {
left.merge(
e.getKey(),
e.getValue(),
(l1, l2) -> {
l1.addAll(l2);
return l1;
});
}
});
System.out.println(result); // {a=[1, 3], b=[2]}
答案 2 :(得分:1)
根据你的评论,我想你可以这么简单。
List<Choice> choices = new ArrayList<>();
Map<String, Integer> map = choices.stream().collect(Collectors.toMap(Choice::getString, Choice::getID);
我建议使用Collectors
及其静态方法,而不是编写自己的供应商和累加器,这些方法用于将流传输到任何类型的集合。
修改强>
如果地图的值必须为Choice
。函数接口具有名为identity()
的静态方法(在调用collect之前的最后一个流转换的类型,在此示例中为Choice
)。
Map<String, Choice> map = choices.stream().collect(Collectors.toMap(Choice::getString, Function.identity());
答案 3 :(得分:0)
Map map = list1.stream()。collect(() - &gt; new HashMap(),(r,s) - &gt; r.put(s.getString(),s),(r,s) - &gt; r.putAll(s));