Как избежать IllegalStateException: повторяющийся ключ в Java 8, когда база данных возвращает повторяющиеся идентификаторы?

База данных возвращает CompanyEntity, которая содержит повторяющийся идентификатор сотрудника.

Map<String, CompanyEntity> pp = allEmployees.stream().collect(Collectors.toMap(CompanyEntity::getEmployeeId, Function.identity()));

Исключение, которое мы получаем:

IllegalStateException: Duplicate key

Есть ли настройка, чтобы предотвратить это в Java 8 без замены ключа, или я должен использовать старый способ Java 6, где я проверяю содержимое и обновляю карту?


person fatherazrael    schedule 07.11.2019    source источник
comment
Почему ваша БД допускает дублирование? Может быть, у вас что-то не так с вашим запросом или структурой БД?   -  person ByeBye    schedule 07.11.2019
comment
@ByeBye: Да, но нужно отфильтровать дубликаты/   -  person fatherazrael    schedule 07.11.2019
comment
Я спросил почему? Возможно, вам нужно решить реальную проблему, а не результат проблемы   -  person ByeBye    schedule 07.11.2019
comment
@ByeBye: Да, но у меня нет доступа к этому, и ленивцы в этой команде не будут этого делать. Обеспокоенность уже высказывалась. Так что мы, бедняги, должны делать всю фильтрацию в интеграциях. (Даже люди отправляют тестовые данные в продакшн, а мы фильтруем их в коде :-D)... ВНУТРЕННИЙ ПРОЕКТ   -  person fatherazrael    schedule 07.11.2019


Ответы (3)


Подстройкой может быть функция слияния для переопределения существующего значения в случае дублирования ключей:

allEmployees.stream()
            .collect(Collectors.toMap(CompanyEntity::getEmployeeId, 
                 Function.identity(), (a,b) -> b))

Но было бы намного лучше определить существующую реализацию как цитируемую где я проверяю, содержит и обновляет карту. Если вы проверяете наличие и не обновляете (put), вместо этого следует использовать (a,b) -> a.

person Naman    schedule 07.11.2019

Вы можете использовать сборщик группировки. Это даст вам уникальные значения employeeId и список вхождений. На втором этапе в сборщике groupingby вы можете получить первый элемент списка. list">Stream groupingBy: сокращение до первого элемента списка и https://www.baeldung.com/java-groupingby-collector

person FredvN    schedule 07.11.2019

что-то вроде этого сработало для меня:

// this.fsRepo.getDosIdsWithDcs(dosIds) обычно возвращает список‹›

 return this.fsRepo.getDosIdsWithDcs(dosIds).
        stream().collect
                (Collectors.toMap(YourModelDosClass::getDosId, v->v,
                        (v1,v2) -> v1));
person Alferd Nobel    schedule 30.11.2020