问题
// 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())));
This code compiles fine in Eclipse Mars, but gets the following eror in Eclipse Luna:
Type mismatch: cannot convert from
Map<Object,List<Object>>
toMap<String,List<WeblabInfo>>
If I do not assign the returned to a Map
with Map<String, List<Item>> managersItem =
in Eclipse Luna, the error is at Map.Entry::getKey
and Map.Entry::getValue
statement with message:
The type
Map.Entry
does not definegetKey(Object)
that is applicable here".
What did I do wrong?
回答1:
You didn't do anything wrong. Eclipse compiler has problems with type inference that causes these issues. If Luna compatibility is important, you will have to add explicit types to lambda expressions. Try, for example, Map.Entry::<String,Item>getKey
On another note, it's not necessary to convert a List
to array to stream it. You can directly call users.stream()
. But even creating the List
isn't necessary. You can use Stream.concat(Stream.of(item.getCreator()), item.getOwners().stream())
instead (granted, it's a bit unwieldy).
Finally (and most importantly), avoid using parallelStream
with blocking code, such as looking up data in an external system. Parallel streams are designed to handle CPU-bound tasks.
回答2:
I was able to come up with this solution from Misha's answer. This is working with Eclipse Luna Java compiler
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())));
来源:https://stackoverflow.com/questions/33091946/java-8-stream-flatmap-and-group-by-code-compiler-error