Reputation: 127
I'm looking for a statment to check if there is any match in two lists of Users, according to Username.
List<User> a;
List<User> b;
for (User user : a) {
for (User newUser : b) {
if (user.getName().equals(newUser.getName())) {
}
}
}
How can I write this in java 8? Somthing like this:
List<User> intersect = a.stream()
.filter(User::getName)
.collect(Collectors.toList());
Upvotes: 2
Views: 9260
Reputation: 109547
When User is correctly defined with a hashCode
and equals
(otherwise you might try TreeSet
instead of HashSet
), do set-operations:
Set<User> common = new HashSet<>(a);
common.retainAll(b);
If User.getName
is not used for equality:
Set<User> common = new TreeSet<>(Comparator.comparing(User::getName));
common.addAll(a);
common.retainAll(b);
Two nested for loops on lists (also as streams) would have complexity O(N²), whereas this is O(N.log N).
Upvotes: 3
Reputation: 31878
One way to do that using Stream.anyMatch
(this would break
within if
) could be :
a.stream().filter(user -> b.stream().anyMatch(newUser -> user.getName().equals(newUser.getName())))
.map(User::getName)
.forEach(System.out::println); // logic inside 'if' here (print for e.g.)
If you want to repeat the loop(if
logic) for all such matches :
a.forEach(user -> b.stream()
.filter(newUser -> user.getName().equals(newUser.getName()))
.map(newUser -> user.getName())
.forEach(System.out::println));
Upvotes: 1
Reputation: 2280
You can do something like below:
List<User> intersect = a.stream()
.filter(b::contains)
.collect(Collectors.toList());
You need to override equals
and hashCode
methods in User
.
For optimization, you can convert b
to HashSet
first.
Upvotes: 2