I want to iterate two lists and get new filtered list which will have values not present in second list. Can anyone help?
I have two lists - one is list of strings,
@DSchmdit answer worked for me. I would like to add on that. So my requirement was to filter a file based on some configurations stored in the table. The file is first retrieved and collected as list of dtos. I receive the configurations from the db and store it as another list. This is how I made the filtering work with streams
List<FPRSDeferralModel> modelList = Files
.lines(Paths.get("src/main/resources/rootFiles/XXXXX.txt")).parallel().parallel()
.map(line -> {
FileModel fileModel= new FileModel();
line = line.trim();
if (line != null && !line.isEmpty()) {
System.out.println("line" + line);
fileModel.setPlanId(Long.parseLong(line.substring(0, 5)));
fileModel.setDivisionList(line.substring(15, 30));
fileModel.setRegionList(line.substring(31, 50));
Map<String, String> newMap = new HashedMap<>();
newMap.put("other", line.substring(51, 80));
fileModel.setOtherDetailsMap(newMap);
}
return fileModel;
}).collect(Collectors.toList());
for (FileModel model : modelList) {
System.out.println("model:" + model);
}
DbConfigModelList respList = populate();
System.out.println("after populate");
List<DbConfig> respModelList = respList.getFeedbackResponseList();
Predicate<FileModel> somePre = s -> respModelList.stream().anyMatch(respitem -> {
System.out.println("sinde respitem:"+respitem.getPrimaryConfig().getPlanId());
System.out.println("s.getPlanid()"+s.getPlanId());
System.out.println("s.getPlanId() == respitem.getPrimaryConfig().getPlanId():"+
(s.getPlanId().compareTo(respitem.getPrimaryConfig().getPlanId())));
return s.getPlanId().compareTo(respitem.getPrimaryConfig().getPlanId()) == 0
&& (s.getSsnId() != null);
});
final List<FileModel> finalList = modelList.stream().parallel().filter(somePre).collect(Collectors.toList());
finalList.stream().forEach(item -> {
System.out.println("filtered item is:"+item);
});
The details are in the implementation of filter predicates. This proves much more perfomant over iterating over loops and filtering out
If you stream the first list and use a filter based on contains within the second...
list1.stream()
.filter(item -> !list2.contains(item))
The next question is what code you'll add to the end of this streaming operation to further process the results... over to you.
Also, list.contains is quite slow, so you would be better with sets.
But then if you're using sets, you might find some easier operations to handle this, like removeAll
Set list1 = ...;
Set list2 = ...;
Set target = new Set();
target.addAll(list1);
target.removeAll(list2);
Given we don't know how you're going to use this, it's not really possible to advise which approach to take.
`List<String> unavailable = list1.stream()
.filter(e -> (list2.stream()
.filter(d -> d.getStr().equals(e))
.count())<1)
.collect(Collectors.toList());`
for this if i change to
`List<String> unavailable = list1.stream()
.filter(e -> (list2.stream()
.filter(d -> d.getStr().equals(e))
.count())>0)
.collect(Collectors.toList());`
will it give me list1 matched with list2 right?
Doing it with streams is easy and readable:
Predicate<String> notIn2 = s -> ! list2.stream().anyMatch(mc -> s.equals(mc.str));
List<String> list3 = list1.stream().filter(notIn2).collect(Collectors.toList());
See below, would welcome anyones feedback on the below code.
not common between two arrays:
List<String> l3 =list1.stream().filter(x -> !list2.contains(x)).collect(Collectors.toList());
Common between two arrays:
List<String> l3 =list1.stream().filter(x -> list2.contains(x)).collect(Collectors.toList());
list1 = list1.stream().filter(str1->
list2.stream().map(x->x.getStr()).collect(Collectors.toSet())
.contains(str1)).collect(Collectors.toList());
This may work more efficient.