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 中没有将返回值分配给 MapMap<String, List<Item>> managersItem =,则错误出现在 Map.Entry::getKeyMap.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())));