Java 8 Strem фильтр карта на карте - Карта> - PullRequest
0 голосов
/ 26 декабря 2018

Как отфильтровать Map<String,Map<String,Employee>> с помощью Java 8 Filter?

Я должен фильтровать, только когда кто-либо из сотрудников в списке имеет значение поля Gender = "M".

Ввод:

Map<String,Map<String,Employee>>

Вывод:

Map<String,Map<String,Employee>>

Критерии фильтра:

Employee.genter = "M"

Также я должен вернуть пустую карту, если отфильтрованный результат пуст.

Я пробовал ниже, но это не работает какожидается.Возвращается только в том случае, если все сотрудники имеют пол "M".

tempCollection.entrySet().stream()
                        .filter(i -> i.getValue().entrySet().stream().allMatch(e-> "M".equals(e.getValue().getGender())))
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Ответы [ 5 ]

0 голосов
/ 26 декабря 2018

Другой способ будет выглядеть так:

map.values()
     .removeIf(entry->entry.values().stream().anyMatch(e -> !"M".equals(e.getGender())));

map.entrySet()
    .removeIf(entry->entry.getValue().size() == 0);
0 голосов
/ 26 декабря 2018

Вы можете сделать это следующим образом:

Map<String, Map<String, Employee>> maleEmpMap = tempCollection.entrySet().stream()
    .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(),
        e.getValue().entrySet().stream().filter(emp -> "M".equals(emp.getValue().getGender()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Возьмите каждую запись карты с внешней карты и создайте новую запись карты, используя тот же ключ, и вновь созданную вложенную карту с тем же ключом, которая имееттолько работники мужского пола, поскольку это ценность.Наконец соберите все соответствующие записи в новую внешнюю карту.Это изящно обработает пустой сценарий, который вы упомянули в постановке задачи выше.

0 голосов
/ 26 декабря 2018

Похоже, что после того, как вы получаете, выдается Entry<String,Map<String,Employee>>, если есть какой-либо сотрудник, у которого пол "M", затем отфильтруйте внутренний Map<String,Employee>, чтобы он содержал только записи с полом "M".

, в этом случае вы можете filter вместе с anyMatch для первого критерия.Далее, на этапе сбора вы можете применить фильтрацию к внутренней карте:

tempCollection.entrySet().stream()
            .filter(i -> i.getValue().values().stream().anyMatch(e -> "M".equals(e.getGender())))
            .collect(toMap(Map.Entry::getKey,
                    v -> v.getValue().entrySet().stream()
                            .filter(i -> "M".equals(i.getValue().getGender()))
                            .collect(toMap(Map.Entry::getKey, Map.Entry::getValue))));
0 голосов
/ 26 декабря 2018

Функция allMatch соответствует, только если каждый элемент в потоке соответствует предикату;вы можете использовать anyMatch для сопоставления, если какой-либо элемент соответствует предикату:

tempCollection.entrySet().stream()
                        .filter(i -> i.getValue().entrySet().stream().anyMatch(e-> "M".equals(e.getValue().getGender())))
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
0 голосов
/ 26 декабря 2018

Вы можете просто перебрать пары ключ-значение и отфильтровать как:

Map<String, Map<String, Employee>> output = new HashMap<>();
tempCollection.forEach((k, v) -> {
    if (v.values().stream().anyMatch(i -> "M".equals(i.getGender()))) {
        output.put(k, v.entrySet()
                .stream()
                .filter(i -> "M".equals(i.getValue().getGender()))
                .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)));
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...