Stream Filter of 1 list based on another list

We Are Going To Discuss About Stream Filter of 1 list based on another list. So lets Start this Java Article.

Stream Filter of 1 list based on another list

  1. Stream Filter of 1 list based on another list

    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.

  2. Stream Filter of 1 list based on another list

    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.

Solution 1

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

Original Author Alexis C. Of This Content

Solution 2

in your DataCar type, does getName() return a String or the DataCarName enum type? If it is the enum, you might follow Alexis C’s approach but instead of building a HashSet using Collectors.toSet(), build an EnumSet, which gives O(1) performance. Modifying Alexis’ suggestion, the result would look like:

Set<DataCarName> carNames = 
    listCarName.stream()
               .collect(Collectors.toCollection(
                   ()-> EnumSet.noneOf(DataCarName.class)));

List<DataCar> listOutput =
    listCar.stream()
               .filter(car -> carNames.contains(car.getName()))  
               .collect(Collectors.toList());

Original Author Hank D Of This Content

Solution 3

@Alexis’a answer is nice, but I have another way around to get use of performance from Map and improve the part you do listCarName.stream().map(DataCarName::getName).anyMatch(name -> name.equals(e.getName())) for each item, first I make a map from listCar and making the key with the field that I want to compare, in this instance is car’s name and filter out null values when I map the list1 to be CarData.

So it should be something like:

final Map<String, CarData> allCarsMap = listCar // Your List2
    .stream().collect(Collectors.toMap(CarData::getName, o -> o));

final List<CarData> listOutput = // Your expected result
    listCarName // Your List1
      .stream()
      .map(allCarsMap::get) // will map each name with a value in the map
      .filter(Objects::nonNull) // filter any null value for any car name that does not exist in the map
      .collect(Collectors.toList());

I hope this helps, maybe a little better performance in some scenarios?

Original Author Al-Mothafar Of This Content

Solution 4

Try this: 

SortedMap<String, Account> accountMap, List<AccountReseponse> accountOwnersList

 List<Map.Entry<String, Account>> entryList = accountMap.entrySet().stream().filter(account -> accountOwnersList.stream()
                .anyMatch(accountOwner -> accountOwner.getAccount()
                                .getIdentifier().equals(account.getValue().getIdentifier())))
                .collect(Collectors.toList());

Can also use .noneMatch().

Original Author Smart Coder Of This Content

Conclusion

So This is all About This Tutorial. Hope This Tutorial Helped You. Thank You.

Also Read,

Siddharth

I am an Information Technology Engineer. I have Completed my MCA And I have 4 Year Plus Experience, I am a web developer with knowledge of multiple back-end platforms Like PHP, Node.js, Python and frontend JavaScript frameworks Like Angular, React, and Vue.

Leave a Comment