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
- Stream Filter of 1 list based on another list
It's not clear why you have a
List<DataCarName>
in first place instead of aList/Set<String>
.
The predicate you have to provide must check if for the corresponding data car instance, there's its name in the list. - Stream Filter of 1 list based on another list
It's not clear why you have a
List<DataCarName>
in first place instead of aList/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.