Iterate and filter two lists with java 8

I want to iterate over two lists and get a new filtered list that will have values โ€‹โ€‹not in the second list. Can anyone help?

I have two lists: one is a list of strings, and the other is a list of MyClass objects.

 List<String> list1; List<MyClass> list2; MyClass { MyClass(String val) { this.str = val; } String str; ... ... } 

I want a filtered list of strings based on โ†’ check the second list for elements (abc) whose values โ€‹โ€‹are not in list1 .

 List<String> list1 = Arrays.asList("abc", "xyz", "lmn"); List<MyClass> list2 = new ArrayList<MyClass>(); MyClass obj = new MyClass("abc"); list2.add(obj); obj = new MyClass("xyz"); list2.add(obj); 

Now I need a new filtered list -> which will have value => "lmn". that is, values โ€‹โ€‹not in list2 whose elements are in list1 .

+12
source share
10 answers

Finally, I got a way to achieve this as follows -

 List<String> unavailable = list1.stream() .filter(e -> (list2.stream() .filter(d -> d.getStr().equals(e)) .count())<1) .collect(Collectors.toList()); 

But it also works as expected. Please let me know how effective this is? and if anyone has another way to do the same?

+5
source
 // produce the filter set by streaming the items from list 2 // assume list2 has elements of type MyClass where getStr gets the // string that might appear in list1 Set<String> unavailableItems = list2.stream() .map(MyClass::getStr) .collect(Collectors.toSet()); // stream the list and use the set to filter it List<String> unavailable = list1.stream() .filter(e -> unavailableItems.contains(e)) .collect(Collectors.toList()); 
+18
source

Doing this with threads is easy and affordable:

 Predicate<String> notIn2 = s -> ! list2.stream().anyMatch(mc -> s.equals(mc.str)); List<String> list3 = list1.stream().filter(notIn2).collect(Collectors.toList()); 
+7
source

If you pass the first list and use a filter based on contains for the second ...

 list1.stream() .filter(item -> !list2.contains(item)) 

The next question is what code will you add at the end of this streaming operation to further process the results ... to you.

Also, list.contains is pretty slow, so you will be better off with sets.

But if you use sets, you can find some simpler operations for this, like removeAll

 Set list1 = ...; Set list2 = ...; Set target = new Set(); target.addAll(list1); target.removeAll(list2); 

Given that we do not know how you are going to use this, it is actually impossible to give some kind of approach.

+4
source

A simple approach is foreach in list1 and checks if an item is in list2 if not added to list3.

 outer: for(String s : list1) { for(MyClass c : list2) if(c.getStr().equals(s)) continue outer; filteredList.add(c); } 

If you find that you are still not confusing, extract the inner loop into the boolean function. You can also replace the classic foreach for the lambda stream iterator.

 public static boolean isInList(ArrayList<MyClass> list, String s) { list2.stream().foreach((o)-> { if(o.getStr().equals(s)) { return true; } }); return false; } list1.stream().foreach((s) -> { if(!isInList(list2, s)) { list3.add(s); } }); 

but it really looks more unsightly / dirty and unnecessary for my eyes.

In addition, String str in your class does not have an open definition, so I used the getStr () method in both examples, assuming your class follows the java bean model and contains the getStr () method.

+2
source

See below will welcome feedback on the code below.

does not exist 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()); 
+2
source
 list1 = list1.stream().filter(str1-> list2.stream().map(x->x.getStr()).collect(Collectors.toSet()) .contains(str1)).collect(Collectors.toList()); 

This may work more efficiently.

+1
source

if you have a class with id and you want to filter by id

line1: you print all identifiers

line2: filter out what doesn't exist on the map

 Set<String> mapId = entityResponse.getEntities().stream().map(Entity::getId).collect(Collectors.toSet()); List<String> entityNotExist = entityValues.stream().filter(n -> !mapId.contains(n.getId())).map(DTOEntity::getId).collect(Collectors.toList()); 
0
source

@DSchmdit's answer worked for me. I would add to this. So my requirement was to filter the file based on some configurations stored in the table. The file is first extracted and compiled as a dtos list. I get the configurations from the database and save them as another list. This is how I made filtering work with threads

  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); }); 

Details in the implementation of the predicate filter. This proves that iterating over loops and filtering is much more efficient.

0
source
 '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? 
0
source

Source: https://habr.com/ru/post/984779/


All Articles