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

Use Java Stream to filter list based on values from second list

you should use filter on main collection and !contains on List collection

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Scratch {
static class Element {
int id;
String name;
String description;

public Element(int id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
}

@Override
public String toString() {
return "Element{" +
"id=" + id +
", name='" + name + '\'' +
", description='" + description + '\'' +
'}';
}
}

public static void main(String[] args) {
List<Element> elements = new ArrayList<>(Arrays.asList(
new Element(12345, "nameofitem", "asdfafd"),
new Element(34567, "nameofitem", "asdfafd"),
new Element(56789, "nameofitem", "asdfafd")
));
List<Integer> filterNot = new ArrayList<>(Arrays.asList(12345, 56789));
List<Element> result = elements.stream().filter(item -> !filterNot.contains(item.id)).collect(Collectors.toList());

result.forEach(System.out::println);
}

}

Java Stream: Filter list 1 based on the objects present in list 2

You can first flatten the nested lists and extract the names of the car models from the list as a HashSet. :

Set<String> names = carDataList.stream()
.flatMap(cd -> cd.getCarDetails().stream())
.flatMap(det -> det.getCars().stream())
.map(Car::getModelName())
.collect(Collectors.toCollection(HashSet::new));

You can now use this set's contains() method to filter your List<CarModel>:

models.stream()
.filter(model -> names.contains(model.getModel()))
.collect(Collectors.toList())
.forEach(m -> System.out.println(m.getModel()));

If you just want the names in the list:

models.stream()
.map(CarModel::getModel)
.filter(names::contains)
.collect(Collectors.toList())
.forEach(System.out::println);

Filter `List` based on another `List`

Use map instead of filter:

public List<Integer> filter(List<Integer> lines, List<Integer> programLines)              
List<Integer> listOutput =
lines.stream()
.map(i -> programLines.contains(i) ? i : 0)
.collect(Collectors.toList());
return listOutput;
}

If programLines is large, it may be useful to convert it to a Set for better performance:

public List<Integer> filter(List<Integer> lines, List<Integer> programLines)              
Set<Integer> filter = new HashSet<>(programLines);
List<Integer> listOutput =
lines.stream()
.map(i -> filter.contains(i) ? i : 0)
.collect(Collectors.toList());
return listOutput;
}

Java 8: Filter list inside object with another list

Streams shouldn't be used to modify the List. Instead you should return a new List with only the appropriate elements in it. You could simply flip the logic a little and use filter:

foodList.stream().flatMap(e -> e.categories.stream())
.filter(c -> !excludedCategories.contains(c))
.collect(Collectors.toList());

However it would be much simpler to use the built in methods:

foodList.removeIf(e -> !Collections.disjoint(e.categories, excludedCategories));

Collections::disjoint

Collections::removeIf

Fetch list of objects in one list that are not part of another list using Java stream filter

Negation should be inside filter, since anyMatch returns true if at least one match found

List<TestSVM> results = listOne.stream().filter(one-> !listTwo.stream()
.anyMatch(two -> two.getSchool().equals(one.getSchool())))
.collect(Collectors.toList());


Related Topics



Leave a reply



Submit