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
How to Serialize an Object That Includes Bufferedimages
Dynamically Adding Items to a Jcombobox
Why in Java Enum Is Declared as Enum<E Extends Enum<E>>
Org.Openqa.Selenium.Webdriverexception: Unknown Error: Call Function Result Missing 'Value'
JPA SQL Server No Dialect Mapping for Jdbc Type: -9
Printf %F with Only 2 Numbers After the Decimal Point
How to Change Java Logging Console Output from Std Err to Std Out
Why Can't You Reduce the Visibility of a Method in a Java Subclass
Does Java Guarantee That Object.Getclass() == Object.Getclass()
Generics with Spring Resttemplate
How to Search in a List of Java Object
Hibernate/JPA - Annotating Bean Methods VS Fields
How to Create a Stream of Regex Matches
Error:Java.Lang.Nosuchmethoderror: Org.Objectweb.Asm.Classwriter.<Init>(I)V
Programmatically Import Ca Trust Cert into Existing Keystore File Without Using Keytool