Java Person对象包含枚举集。如何使用聚合函数/lambda将List转换为EnumMap
我试图学习Java中的聚合函数和lambda。我有一门课:Java Person对象包含枚举集。如何使用聚合函数/lambda将List转换为EnumMap,java,lambda,java-8,aggregate-functions,Java,Lambda,Java 8,Aggregate Functions,我试图学习Java中的聚合函数和lambda。我有一门课: public class Person { public enum Privilege{ PRIV1, PRIV2, PRIV3, PRIV4, PRIV4 } private String name; private Set<Privilege> privileges; ... } 以及该类对象的列表。 我想把它转换成EnumMap 其中列表包含具有特定特权的所有人员的姓名
public class Person {
public enum Privilege{
PRIV1, PRIV2, PRIV3, PRIV4, PRIV4
}
private String name;
private Set<Privilege> privileges;
...
}
以及该类对象的列表。
我想把它转换成EnumMap
其中列表包含具有特定特权的所有人员的姓名。我创建了一个方法来执行此操作:
public static Map<Privilege,List<String>> personsByPrivilege(List<Person> personList){
Map<Privilege, List<String>> resultMap = new EnumMap(Privilege.class);
Arrays.asList(Privilege.values())
.stream()
.forEach(p->resultMap.put(p,new ArrayList<String>()));
for(Person p :personList){
Set<Privilege> personsPrivileges = p.getPrivileges();
for(Privilege pr : personsPrivileges){
resultMap.get(pr).add(p.getName());
}
}
return resultMap;
}
如何使用聚合函数来实现它?
我的意思是,例如personlist.stream.collect样式您可以将person->list of privileges平铺成成对,然后按权限分组,并使用名称进行映射
public static Map<Person.Privilege, List<String>> personsByPrivilegeB(List<Person> personList) {
return personList.stream()
.flatMap(pers -> pers.getPrivileges().stream().map(priv -> new Object[]{priv, pers.getName()}))
.collect(groupingBy(o -> (Person.Privilege) o[0], mapping(e -> (String) e[0], toList())));
}
您可以添加Pair类并使用以下代码来实现您的目标
return personList.stream().flatMap(p -> {
String name = p.getName();
return p.getPrivileges().stream()
.flatMap(priv -> Stream.of(new NamePriviledge(priv, name)));
}).collect(Collectors.groupingBy(NamePriviledge::getPrivilege, Collectors.mapping(NamePriviledge::getName, Collectors.toList())));
}
class NamePriviledge {
private final Person.Privilege privilege;
private final String name;
public NamePriviledge(Person.Privilege privilege, String name) {
this.privilege = privilege;
this.name = name;
}
public String getName() {
return name;
}
public Person.Privilege getPrivilege() {
return privilege;
}
@Override
public String toString() {
return "NamePriviledge{" +
"privilege=" + privilege +
", name='" + name + '\'' +
'}';
}
}
聚合函数对您来说是什么?我的意思是,例如personlist.stream.collect样式,对于Person-per:personlist{for Privilege-priv:per.getPrivileges{resultMap.computeFabsentNew ArrayList.addper.getName;}}更简单。@Johaneskun这是computeFabsentPriv,key->new ArrayList,但我同意,这是最简单的解决方案。为了便于操作,可以使用forEach而不是循环,personList.forEachper->per.getPrivileges.forEachpriv->computeIfAbsentpriv,key->newarraylist.addper.getName;是的,错过了。谢谢。问题是每个输入元素的人可能在零个或多个组中。您不能只使用groupingBy,因为这只允许您将每个输入元素分配给一个组