Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream Filter of 1 list based on another list

I am posting my query after having searched in this forum & google, but was unable to resolve the same. eg: Link1 Link2 Link3

I am trying to filter List 2 (multi column) based on the values in List 1.

List1:  - [Datsun]  - [Volvo]  - [BMW]  - [Mercedes]  List2:   - [1-Jun-1995, Audi, 25.3, 500.4, 300]  - [7-Apr-1996, BMW, 35.3, 250.2, 500]  - [3-May-1996, Porsche, 45.3, 750.8, 200]  - [2-Nov-1998, Volvo, 75.3, 150.2, 100]  - [7-Dec-1999, BMW, 95.3, 850.2, 900]  expected o/p:  - [7-Apr-1996, BMW, 35.3, 250.2, 500]  - [2-Nov-1998, Volvo, 75.3, 150.2, 100]  - [7-Dec-1999, BMW, 95.3, 850.2, 900] 

Code

// List 1 in above eg List<dataCarName> listCarName = new ArrayList<>();  // List 2 in above eg List<dataCar> listCar = new ArrayList<>();   // Values to the 2 lists are populated from excel  List<dataCar> listOutput = listCar.stream().filter(e -> e.getName().contains("BMW")).collect(Collectors.toList()); 

In the above code if I provide a specific value I can filter, but not sure how to check if Car Name in List 2 exits in List 1.

Hope the issue I face is clear, await guidance (Am still relatively new to Java, hence forgive if the above query is very basic).

Edit I believe the link-3 provided above should resolve, but in my case it is not working. Maybe because the values in list-1 are populated as org.gradle04.Main.Cars.dataCarName@4148db48 .. etc. I am able to get the value in human readable format only when I do a forEach on List 1 by calling the getName method.

like image 283
iCoder Avatar asked Mar 27 '16 11:03

iCoder


People also ask

How do I filter a list based on another list in Java 8?

After populating both the lists, we simply pass a Stream of Employee objects to the Stream of Department objects. Next, to filter records based on our two conditions, we're using the anyMatch predicate, inside which we have combined all the given conditions. Finally, we collect the result into filteredList.

Can we use two filter in stream?

The Stream API allows chaining multiple filters. We can leverage this to satisfy the complex filtering criteria described. Besides, we can use the not Predicate if we want to negate conditions.

How can you create a stream from the elements of a list variable call list?

Below are various methods to convert List to Stream in Java: Using List. stream() method: Java List interface provides stream() method which returns a sequential Stream with this collection as its source.


1 Answers

It's not clear why you have a List<DataCarName> in first place instead of a List/Set<String>.

The predicate you have to provide must check if for the corresponding data car instance, there's its name in the list.

e -> e.getName().contains("BMW") will only check if the name of the data car contains BMW which is not what you want. Your first attempt then may be

e -> listCarName.contains(e.getName()) 

but since listCarName is a List<DataCarName> and e.getName() a string (I presume), you'll get an empty list as a result.

The first option you have is to change the predicate so that you get a stream from the list of data car names, map them to their string representation and check that any of these names corresponds to the current data car instance's name you are currently filtering:

List<DataCar> listOutput =     listCar.stream()            .filter(e -> listCarName.stream().map(DataCarName::getName).anyMatch(name -> name.equals(e.getName())))            .collect(Collectors.toList()); 

Now this is very expensive because you create a stream for each instance in the data car stream pipeline. A better way would be to build a Set<String> with the cars' name upfront and then simply use contains as a predicate on this set:

Set<String> carNames =      listCarName.stream()                .map(DataCarName::getName)                .collect(Collectors.toSet());  List<DataCar> listOutput =      listCar.stream()             .filter(e -> carNames.contains(e.getName()))             .collect(Collectors.toList()); 
like image 151
Alexis C. Avatar answered Sep 22 '22 07:09

Alexis C.