Получение List отсутствующих объектов в одном из двух List

имеется объект Comment c атрибутами

Long id;
User author;
String body;

В данный момент ко мне в метод приходят 2 списка, нужно проверить есть ли во втором списке значения из первого, и если нет то добавить их в лист и вернуть наружу:

private List<Comment> getCommentList(List<Comment> parentComments, List<Comment> childComments){
    List<Comment> list = new ArrayList<>();
    list.addAll(parentComments.stream()
            .filter(pc -> !childComments.contains(pc))
            .collect(toList()));
    return list;
}

В данный момент могут приходить одинаковые body но разные ID. Я так понимаю что contains() тут не подходит потому что объекты по сути приходят разные. Как мне внутрь добавить проверку ещё и по нужным мне атрибутам? Мне нужно решение без переопределения equals().


Ответы (1 шт):

Автор решения: Zhenyria

Решение с equals()

Просто переопределите equals() в объекте Comment, чтобы сравнение происходило именно так, как вам надо, то есть без учёта ID, но с учётом всех остальных полей. ArrayList#contains использует equals() объекта, так что он будет работать правильно.

Ну учтите, что поле author - это тоже объект, а значит, он тоже должен сравниваться корректно (впрочем, может в вашем случае и сравнение по ссылкам сойдёт).

Решение без equals() со сложностью O(N^2)

Сделайте простой перебор в filter. Вот так:

list.addAll(
    parentComments
        .stream()
            .filter(pc -> {
                for (Comment child : childComments) {
                    boolean isAuthorEquals = child.getAuthor().equals(pc.getAuthor());
                    boolean isBodyEquals = child.getBody().equals(pc.getBody());
                    if (isAuthorEquals && isBodyEquals) {
                       return false;
                    }
                }
            })
            .collect(toList()));

Что-то вроде этого. Сравниваем свойства вручную. Можно ещё реализовать свой Comparator, чтобы код был почище, я лишь показываю общую идею. Надо учитывать, что на больших объёмах данных падение производительности может быть очень значительным, и данный вариант ни в коем случае не является оптимальным. Но если вы точно знаете, что объёмы данных будут небольшими (а вы это знать наверняка почти точно не сможете), то такой вариант может сгодиться.

→ Ссылка