使用Streams API和Collectors.toMap()使用对象引用作为键构造Map

时间:2015-02-26 08:32:22

标签: java lambda collections java-8 java-stream

我想构建一个Map<Item, List<String>>,即使用Item引用作为键,并使用一些任意List<String>作为值。我尝试了以下内容,但它会在IntelliJ中显示类型推断错误(但是,它仍然会编译);

List<Item> items = getItems(...);
Map<Item, List<String>> itemMap = items.stream().collect(Collectors.toMap(i->i, new ArrayList<>()));

然后,我通过Itemget()中的辅助方法创建了一个解决方法,该方法只返回自己的实例;

public Item get(){ return this; }

然后尝试了相同的方法,使用get()方法访问引用:

List<Item> items = getItems(...);
Map<Item, List<String>> itemMap = items.stream().collect(Collectors.toMap(Item::get, new ArrayList<>()));

现在它至少会编译,但感觉不对

如何以适当的方式解决这个问题?

编辑:问题现在与最初发布的内容截然不同,反映在收到的评论中。

2 个答案:

答案 0 :(得分:2)

在您的第一次尝试中,它应该是:

List<Item> items = getItems(...);
Map<Item, String> itemMap = items.stream()
                                 .collect(Collectors.toMap(i->i, 
                                                           i->"some string"));

您错过了)以及值的lambda表达式的参数名称。

将地图的值更改为列表并没有太大区别:

List<Item> items = getItems(...);
Map<Item, List<String>> itemMap = items.stream()
                                       .collect(Collectors.toMap(i->i, 
                                                                 i->new ArrayList<>()));

答案 1 :(得分:0)

实现它的正确方法是包含类似的类型参数;

List<Item> items = getItems(...);
Map<Item, List<String>> itemMap = items.stream().collect(Collectors.toMap(Function.<Item>identity(), v -> new ArrayList<>()));

可替换地;

List<Item> items = getItems(...);
Map<Item, List<String>> itemMap = items.stream().collect(Collectors.toMap(v -> v, v -> new ArrayList<String>()));