Как сравнить два ArrayList и получить list1 с фильтром, используя потоки Java

У меня есть два списка list1 и list2 типа List

Term{
long sId;
int rowNum;
long psid;
String name;
}

List<Term> list1 = new ArrayList<>();
List<Term> list2 = new ArrayList<>();

Я хочу вернуть все элементы из list1, где (list1.psid! = list2.psid).

Я пробовал это, но это не работает

public List<Term> getFilteredRowNum(List<Term> list1, List<Term> list2) {
        List<Long> psid = list2.stream().map(x -> x.getPsid()).collect(Collectors.toList());

        return list1.stream().filter(x -> !psid.contains(x.getPsid())).map(x -> x.getRowNum()+1).collect(Collectors.toList());

    }

Я хочу получить все записи в list1, которые удовлетворяют следующему условию если(список1.psid != список2.psid)

Sample Date:
List1: rowNum     psId    name    sid
       1         1288     home    101
       1         9012     home    101
       2         1296     office  150
       3         1290     park    161

List2: rowNum     psId    name    sid
       1          9012    home    101
       2         1296     office  150
       3         1290     park    161

List1 psId not in list2 so I am expecting fallowing list as result from list1

Expected: List1
 rowNum     psId    name    sid
 1         1288     home    101
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
0
118
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы ищете внутренний anyMatch в предикате фильтра как:

public List<Term> getFilteredRowNum(List<Term> termList1, List<Term> termList2) {
    return termList1.stream()
            .filter(term1 -> termList2.stream()
                    .anyMatch(term2 -> term1.getSId() == term2.getSId()
                            && term1.getPsid() != term2.getPsid()))
            .collect(Collectors.toList());
}

Другой способ решить эту проблему - создать Map из sid для Set из psid, присутствующих в любом из списка, используя groupingBy и mapping

Map<Long, Set<Long>> sIdToPsIdsMap = termList2.stream()
        .collect(Collectors.groupingBy(Term::getSId, 
                Collectors.mapping(Term::getPsid, Collectors.toSet())));

и далее использовать его для filter условий как

return termList1.stream()
        .filter(term1 -> sIdToPsIdsMap.containsKey(term1.getSId())
                && !sIdToPsIdsMap.get(term1.getSId()).contains(term1.getPsid()))
        .collect(Collectors.toList());

Я просто хотел добавить ваше второе решение, так как оно повышает производительность списков языков. Вы также можете использовать одно условие, используя Map.getOrDefault(): !sIdToPsIdsMap.getOrDefault(term1.getSId(), new HashSet<>()).contains(term1.getPsid()).

Samuel Philipp 25.07.2019 07:16

@SamuelPhilipp, но разве это не всегда будет выполнять проверку contains, несмотря на отсутствие key?

Naman 25.07.2019 07:18

Я пробовал это в соответствии с вашим решением, но это не фильтрация. Я даже пытался найти только одно условие, т. е. psId list1 (не в) psId list2. public List<Term> getFilteredSBDRowNum(List<Term> list1, List<Term> list2) { return list1.stream().filter(term1 -> list2.stream().anyMatch(term2 -> term1.getPsid()!= term2.getPsid())).collect(Collectors.toList()); }

Sruthi 25.07.2019 07:27

@SamuelPhilipp, Наман, это для большего списка, и я должен рассматривать производительность как один из ключевых факторов.

Sruthi 25.07.2019 07:29

@Sruthi Не могли бы вы обновить вопрос, указав пример ввода, ожидаемый результат и текущий результат, который вы получаете? Уточнил бы еще, чего нам не хватает.

Naman 25.07.2019 07:30

@Sruthi, а какой результат вы получаете от второго решения здесь, в решении?

Naman 25.07.2019 07:50

@Naman Я не пробовал второе решение. первое решение. Я получаю весь список1 как есть. попробуем решение Map<Long, Set<Long>>

Sruthi 25.07.2019 07:52

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

Naman 25.07.2019 08:00

@Naman не работает, выдает синтаксическую ошибку. Также я хочу сгруппировать по rowNum.

Sruthi 25.07.2019 08:00

@Naman хорошо, я отлажу и теперь посмотрю, где что-то не так.

Sruthi 25.07.2019 08:01

@Sruthi Ну, вопрос или образцы на самом деле не упоминали о groupingBy с rowNum. Обновите вопрос с полной информацией при его публикации. Тем не менее, если это решение работает, попробуйте groupingBy rowNum самостоятельно и задайте отдельный вопрос, если это вас где-то застряло. (Просто убедитесь, что вы указали полную информацию, когда публикуете вопрос.)

Naman 25.07.2019 08:03

@Naman хорошо, конечно, опубликую вопросы о различиях. Спасибо за помощь.

Sruthi 25.07.2019 08:05

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