Добавляйте объект X в коллекцию только в том случае, если коллекция не содержит объекта с одним совпадающим свойством

Я только начал возиться с потоками Java и написал что-то вроде этого:

List<Device> devicesToDelete = new ArrayList<>();
List<Device> oldDeviceList = getCurrentDevices();

for (Device deviceFromOldList : oldDeviceList)
{
    // part to simplify

    boolean deviceNotExistOnDeleteList =
        devicesToDelete.stream().noneMatch(nd -> nd.id == deviceFromOldList.id);

    if (deviceNotExistOnDeleteList) {
        devicesToDelete.add(deviceFromOldList);
    }

    // part to simplify end
}

Можно еще упростить?

Я не использую Set, потому что моя реализация Device класса .equals() сравнивает все поля в этом классе. А здесь мне нужно сравнить только поле id.

"Я не использую Set, потому что моя реализация Device класса .equals() сравнивает все поля в этом классе. А здесь мне нужно сравнить только поле id." - TreeSet(Comparator<? super E>)?

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

Ответы 1

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

Просто используйте Map

Map<Object, Device> devicesToDelete = new HashMap<>();
List<Device> oldDeviceList = getCurrentDevices();

for(Device deviceFromOldList: oldDeviceList) {
    devicesToDelete.putIfAbsent(deviceFromOldList.id, deviceFromOldList);
}

// in case you need a Collection:
Collection<Device> allDevicesToDelete = devicesToDelete.values();

putIfAbsent сохранит сопоставление только в том случае, если ключ еще не присутствует. Это даст вам производительность хеширования, учитывая только идентификатор.

Вы можете изменить аргумент типа Object в Map<Object,Device> на любой тип вашего идентификатора, хотя это не имеет значения для операции, если все, что вам нужно в конце, это Collection<Device>.

Вы можете использовать поток, например.

Map<Object, Device> devicesToDelete = getCurrentDevices().stream()
    .collect(Collectors.toMap(
        deviceFromOldList -> deviceFromOldList.id, Function.identity(), (a,b) -> a));

хотя спорно, является ли это необходимым изменением. Шлейф не плохой.

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