卡在lambda表达式和地图上 [英] Stuck with lambda expression and Map
问题描述
我有Person
类:
import java.util.*;
public class Person {
private String name;
Map<String,Integer> Skills=new HashMap<>(); // skill name(String) and level(int)
public String getName(){
return this.name;
}
public Map<String,Integer> getSkills(){
return this.Skills;
}
}
和App
类:
import java.util.*;
import java.util.Map.Entry;
import static java.util.stream.Collectors.*;
import static java.util.Comparator.*;
public class App {
private List<Person> people=new ArrayList<>(); // the people in the company
public Map<String,Set<String>> PeoplePerSkill(){
return this.people.stream().collect(groupingBy(p-> p.getSkills().keySet() //<-get
//^problem here
,mapping(Person::getName,toSet())));
}
}
在App
类中,PeoplePerSkill
方法需要按技能返回人员名称的Set
.这意味着一项技能可以被很多人拥有.
In the App
class the PeoplePerSkill
method need to return the Set
of people names per skill. It means a skill could be owned by many people.
我坚持使用groupingBy(p->p..........., )
,只是无法获得技能名称的String
,我尝试了很多方法,但是事情变得陌生了:(.
I stuck with the groupingBy(p->p..........., )
I just can't get the String
of skill's name, I tried so many ways but things get way stranger :(.
顺便说一句,目前我的代码返回Map<Object, Set<String>>
By the way, currently my code returns Map<Object, Set<String>>
推荐答案
您可以通过平面映射来完成此操作,尽管它看起来可能并不十分漂亮:
You can do it via flat-mapping, though it probably doesn't look very beautiful:
public Map<String,Set<String>> PeoplePerSkill(){
return this.people.stream()
.<Entry<String, String>>flatMap(p ->
p.getSkills().keySet()
.stream()
.map(s -> new AbstractMap.SimpleEntry<>(s, p.getName())))
.collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toSet())));
}
在这里flatMap
创建一个对(skill, person name)
对的流,它们的收集方式与您非常相似.我正在使用AbstractMap.SimpleEntry
类来表示该对,您可以使用其他一些东西.
Here flatMap
creates a stream of pairs (skill, person name)
, which are collected in the manner quite similar to yours. I'm using the AbstractMap.SimpleEntry
class to represent the pair, you may use something else.
使用我的 StreamEx 库,可以更轻松地解决此任务:
Using my StreamEx library this task can be solved prettier:
return StreamEx.of(this.people)
.mapToEntry(p -> p.getSkills().keySet(), Person::getName)
.flatMapKeys(Set::stream)
.grouping(toSet());
内部几乎一样,只是语法糖.
Internally it's almost the same, just syntactic sugar.
更新:似乎我原来的解决方案是错误的:它返回了地图person_name -> [skills]
,但是如果我正确理解了OP,他会想要地图skill -> [person_names]
.答案已编辑.
Update: seems that my original solution was wrong: it returned map person_name -> [skills]
, but if I understand the OP correctly, he wants map skill -> [person_names]
. The answer edited.
这篇关于卡在lambda表达式和地图上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!