Список Java <E>на картугде ключ является некоторым свойством E и значение E с этим свойством - PullRequest
0 голосов
/ 02 марта 2019

Я хотел бы, как преобразовать список Java в карту.Если ключ на карте - это какое-то свойство элемента списка (разные элементы могут иметь одно и то же свойство), а значение - это список этих элементов списка (имеющих одно и то же свойство).например. List<Owner> --> Map<Item, List<Owner>>.Я нашел несколько List до Map вопросов, но я не хотел это делать.

Я пришел с:

    List<Owner> owners = new ArrayList<>(); // populate from file

    Map<Item, List<Owner>> map = new HashMap<>();

    owners.parallelStream()
            .map(Owner::getPairStream)
            .flatMap(Function.identity())
            .forEach(pair -> {
                map.computeIfPresent(pair.getItem(), (k,v)-> {
                    v.add(pair.getOwner());
                    return v;
                });
                map.computeIfAbsent(pair.getItem(), (k) -> {
                    List<Owner> list = new ArrayList<>();
                    list.add(pair.getOwner());
                    return list;
                });
            });

PasteBin

Я могу поместить forEach часть в отдельный метод, но он все еще кажется слишком многословным.Кроме того, я сделал Pair класс, чтобы он работал.Я попытался заглянуть в Collectors, но не мог заставить себя сделать то, что хотел.

1 Ответ

0 голосов
/ 02 марта 2019

Откуда вы можете упростить свой код, используя groupingBy:

Map<Item, List<Owner>> map = owners.stream()
        .flatMap(Owner::getPairStream)
        .collect(Collectors.groupingBy(Pair::getItem, 
                Collectors.mapping(Pair::getOwner, 
                                   Collectors.toList())));

Вы также можете отказаться от класса Pair, используя SimpleEntry:

Map<Item, List<Owner>> map = owners.stream()
    .flatMap(owner -> owner.getItems()
                    .stream()
                    .map(item -> new AbstractMap.SimpleEntry<>(item, owner)))
    .collect(Collectors.groupingBy(Entry::getKey, 
                   Collectors.mapping(Entry::getValue, 
                                     Collectors.toList())));

Обратите внимание , что я предполагаю, что Item имеет equals и hashCode, соответственно переопределенные.

Примечания:

  • Вы можетеиспользуйте map.merge вместо последовательных вызовов map.computeIfPresent и map.computeIfAbsent
  • HashMap и parallelStream для создания плохой комбинации (HashMap не является поточно-ориентированным)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...