Извлечение значений на карте

У НАС есть карта Студенты { studentId : StudentData }.
StudentData — это POJO с атрибутами студента.
Требование состоит в том, чтобы получить всех учеников с атрибутом isCurrent==true.
Если да, то извлеките атрибут города для студента.
Это будет использоваться для увеличения количества студентов на карте { city : count }

Students.entrySet()
                .stream()
                .filter(x -> true == x.getValue().isCurrent())
                .forEach(x -> {
                      studentpercity(x.getValue().getCity(), (studentpercity.getOrDefault(x.getValue().getCity(), 0) + 1));
                      });

Конечным результатом будет карта города для подсчета «нынешних» студентов.
Есть ли более эффективный способ добиться этого?

However,this seems to involve multiple iterations of the map. - Как вы думаете, почему требуется несколько итераций? Я вижу одну итерацию над записями карты.
Eran 23.07.2019 09:16

Каков именно желаемый результат? Просто номер для данного города? Или, может быть, Map<String, Integer>, представляющий города и соответствующее количество студентов? Или у вас есть такой Map и вы хотите сделать инкрементные счетчики?

deHaar 23.07.2019 09:25

Я не думаю, что вам нужно фильтровать поток. Вы можете просто добавить оператор if внутри цикла forEach, чтобы «сохранить» итерацию фильтра в потоке.

Saeleas 23.07.2019 09:28
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
3
93
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы можете сделать это так,

Map<String, Long> studentPerCity = students.values().stream().filter(StudentData::isCurrent)
        .collect(Collectors.groupingBy(StudentData::getCity, Collectors.counting()));

Другой вариант может выглядеть так:

students.values().stream()
                .filter(StudenData::isCurrent)
                .map(StudenData::getCity)
                .forEach(city -> studentpercity(city, studentpercity.getOrDefault(city, 0) + 1));

Однако, что касается вашего комментария о «итерациях». В одном потоке (например, в вашем примере) каждый элемент повторяется только один раз. Это означает, что каждая операция в потоке будет применена один раз к каждому элементу и только в том случае, если она не отфильтрована ранее.

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