У меня есть два списка 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




Вы ищете внутренний 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());
@SamuelPhilipp, но разве это не всегда будет выполнять проверку contains, несмотря на отсутствие key?
Я пробовал это в соответствии с вашим решением, но это не фильтрация. Я даже пытался найти только одно условие, т. е. 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()); }
@SamuelPhilipp, Наман, это для большего списка, и я должен рассматривать производительность как один из ключевых факторов.
@Sruthi Не могли бы вы обновить вопрос, указав пример ввода, ожидаемый результат и текущий результат, который вы получаете? Уточнил бы еще, чего нам не хватает.
@Sruthi, а какой результат вы получаете от второго решения здесь, в решении?
@Naman Я не пробовал второе решение. первое решение. Я получаю весь список1 как есть. попробуем решение Map<Long, Set<Long>>
@Sruthi Даже с первым решением я могу подтвердить, что List, возвращенный после использования образца ввода, будет включать в себя только один элемент в выводе, который совпадает с ожидаемым результатом.
@Naman не работает, выдает синтаксическую ошибку. Также я хочу сгруппировать по rowNum.
@Naman хорошо, я отлажу и теперь посмотрю, где что-то не так.
@Sruthi Ну, вопрос или образцы на самом деле не упоминали о groupingBy с rowNum. Обновите вопрос с полной информацией при его публикации. Тем не менее, если это решение работает, попробуйте groupingBy rowNum самостоятельно и задайте отдельный вопрос, если это вас где-то застряло. (Просто убедитесь, что вы указали полную информацию, когда публикуете вопрос.)
@Naman хорошо, конечно, опубликую вопросы о различиях. Спасибо за помощь.
Я просто хотел добавить ваше второе решение, так как оно повышает производительность списков языков. Вы также можете использовать одно условие, используя
Map.getOrDefault():!sIdToPsIdsMap.getOrDefault(term1.getSId(), new HashSet<>()).contains(term1.getPsid()).