Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Person对象包含枚举集。如何使用聚合函数/lambda将List转换为EnumMap_Java_Lambda_Java 8_Aggregate Functions - Fatal编程技术网

Java Person对象包含枚举集。如何使用聚合函数/lambda将List转换为EnumMap

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 其中列表包含具有特定特权的所有人员的姓名

我试图学习Java中的聚合函数和lambda。我有一门课:

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,因为这只允许您将每个输入元素分配给一个组