Соберите List<Object> в Map<String, List<Object>> в Java 8 с использованием потока

Я пытаюсь выполнить эту итерацию, используя поток java 8 вместо традиционного цикла for.

У меня есть список объектов List<Obligation> и Obligation имеет List из String внутри.

Obligation содержит такие поля, как

f1 и f2 типа String,

а также

f3 типа List<String>

Чего я хочу добиться, так это Map<String, List<Obligation>> такого, что String, используемое в ключе Map, представляет собой каждое значение, присутствующее в List<String> от каждого Obligation в List<Obligation>

Вот как код будет выглядеть в традиционном цикле for:

// newly initialized Map
Map<String, List<Obligation>> map = new LinkedHashMap<String, List<Obligation>>();

// assume the list is populated
List<Obligation> obligations = someMethod();

                for(Obligation obligation : obligations) {
                    for(String license : obligation.getLicenseIDs()) {
                        if (map.containsKey(license)) {
                            map.get(license).add(obligation);
                        } else {
                            List<Obligation> list = new ArrayList<Obligation>();
                            list.add(obligation);
                            map.put(license, list);
                        }
                    }
                }

Вопрос хорошо объяснен, хорошие усилия новичка здесь.

Vishwa Ratna 17.07.2019 14:34
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
1
925
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте flatMap, чтобы создать поток пар Obligation и идентификаторов лицензий, а затем используйте groupingBy, чтобы собрать их по идентификатору лицензии.

Map<String, List<Obligation>> map =
    obligations.stream() // Stream<Obligation>
               .flatMap(o -> o.getLicenseIDs()
                              .stream()
                              .map(id -> new SimpleEntry<>(o,id))) // Stream<Map.Entry<Obligation,String>>
               .collect(Collectors.groupingBy(Map.Entry::getValue,
                                              Collectors.mapping(Map.Entry::getKey,
                                                                 Collectors.toList())));

Другие вопросы по теме