Объекты Person содержат EnumSet. Как конвертировать Список <Person>в EnumMap > использование агрегатных функций / лямбд - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь выучить агрегатные функции и лямбды в Java. У меня есть класс:

public class Person {
    public enum Privilege{
        PRIV1, PRIV2, PRIV3, PRIV4, PRIV4
    }
    private String name;
    private Set<Privilege> privileges;
...
}

и список объектов этого класса. Я хочу преобразовать его в EnumMap<Privilege, List<String>>, где список содержит имена всех людей, имеющих определенные привилегии. Я создал метод для этого:

 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 стиль

Ответы [ 2 ]

0 голосов
/ 18 апреля 2020

Вы можете добавить класс 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 + '\'' +
                '}';
    }
}
0 голосов
/ 17 апреля 2020

Вы можете сгладить список лиц -> список привилегий по парам, затем группировать по привилегии и сопоставить с именем

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())));
}
...