Java 8 Stream flatMap and group by 代码编译错误
Java 8 Stream flatMap and group by code compiler error
// given a set of Item objects, group them by the managers of creator and owners
Map<String, List<Item>> managersItems =
itemSet.parallelStream().flatMap(item -> {
// get the list of the creator and owners
List<String> users = new ArrayList();
users.add(item.getCreator());
users.addAll(item.getOwners());
return Stream.of(users.toArray(new String[] {})).map(user -> {
LdapUserInfo ldapUser = LdapUserInfoFactory.create(user);
String manager = ldapUser.getManager();
return new AbstractMap.SimpleImmutableEntry<String, Item(manager, item);
});
}).collect(
Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
此代码在 Eclipse Mars 中编译良好,但在 Eclipse Luna 中出现以下错误:
Type mismatch: cannot convert from Map<Object,List<Object>>
to Map<String,List<WeblabInfo>>
如果我在 Eclipse Luna 中没有将返回值分配给 Map
和 Map<String, List<Item>> managersItem =
,则错误出现在 Map.Entry::getKey
和 Map.Entry::getValue
语句中,消息为:
The type Map.Entry
does not define getKey(Object)
that is applicable here".
我做错了什么?
你没有做错任何事。 Eclipse 编译器存在导致这些问题的类型推断问题。如果 Luna 兼容性很重要,则必须向 lambda 表达式添加显式类型。例如,尝试 Map.Entry::<String,Item>getKey
另一方面,没有必要将 List
转换为数组以对其进行流式传输。可以直接调用users.stream()
。但即使创建 List
也不是必需的。您可以改用 Stream.concat(Stream.of(item.getCreator()), item.getOwners().stream())
(当然,它有点笨拙)。
最后(也是最重要的),避免将 parallelStream
与阻塞代码一起使用,例如在外部系统中查找数据。并行流旨在处理 CPU 绑定任务。
我从 Misha 的回答中得出了这个解决方案。这是使用 Eclipse Luna Java 编译器
Map<String, List<Item>> managersItems = itemSet
.stream()
.<Map.Entry<String, Item>> flatMap(item -> {
return Stream.concat(Stream.of(item.getCreatorLogin()), item.getOwners().stream()).map(
user -> {
LdapUserInfo ldapUser = LdapUserInfoFactory.create(user);
String manager = ldapUser.getManagerLoginName();
return new AbstractMap.SimpleEntry<String, Item>(manager, info);
});
})
.collect(Collectors.groupingBy(Map.Entry<String, Item>::getKey,
Collectors.mapping(Map.Entry<String, Item>::getValue,
Collectors.toList())));
// given a set of Item objects, group them by the managers of creator and owners
Map<String, List<Item>> managersItems =
itemSet.parallelStream().flatMap(item -> {
// get the list of the creator and owners
List<String> users = new ArrayList();
users.add(item.getCreator());
users.addAll(item.getOwners());
return Stream.of(users.toArray(new String[] {})).map(user -> {
LdapUserInfo ldapUser = LdapUserInfoFactory.create(user);
String manager = ldapUser.getManager();
return new AbstractMap.SimpleImmutableEntry<String, Item(manager, item);
});
}).collect(
Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
此代码在 Eclipse Mars 中编译良好,但在 Eclipse Luna 中出现以下错误:
Type mismatch: cannot convert from
Map<Object,List<Object>>
toMap<String,List<WeblabInfo>>
如果我在 Eclipse Luna 中没有将返回值分配给 Map
和 Map<String, List<Item>> managersItem =
,则错误出现在 Map.Entry::getKey
和 Map.Entry::getValue
语句中,消息为:
The type
Map.Entry
does not definegetKey(Object)
that is applicable here".
我做错了什么?
你没有做错任何事。 Eclipse 编译器存在导致这些问题的类型推断问题。如果 Luna 兼容性很重要,则必须向 lambda 表达式添加显式类型。例如,尝试 Map.Entry::<String,Item>getKey
另一方面,没有必要将 List
转换为数组以对其进行流式传输。可以直接调用users.stream()
。但即使创建 List
也不是必需的。您可以改用 Stream.concat(Stream.of(item.getCreator()), item.getOwners().stream())
(当然,它有点笨拙)。
最后(也是最重要的),避免将 parallelStream
与阻塞代码一起使用,例如在外部系统中查找数据。并行流旨在处理 CPU 绑定任务。
我从 Misha 的回答中得出了这个解决方案。这是使用 Eclipse Luna Java 编译器
Map<String, List<Item>> managersItems = itemSet
.stream()
.<Map.Entry<String, Item>> flatMap(item -> {
return Stream.concat(Stream.of(item.getCreatorLogin()), item.getOwners().stream()).map(
user -> {
LdapUserInfo ldapUser = LdapUserInfoFactory.create(user);
String manager = ldapUser.getManagerLoginName();
return new AbstractMap.SimpleEntry<String, Item>(manager, info);
});
})
.collect(Collectors.groupingBy(Map.Entry<String, Item>::getKey,
Collectors.mapping(Map.Entry<String, Item>::getValue,
Collectors.toList())));