Java 8 Lambda filter by Lists

JavaLambdaJava 8

Java Problem Overview


I have two list and i want filter thoose elements which are both list contains. And i want to do this with lambda expression.

Users getName and Clients getUserName both are return with String.

Here is my sample code:

List<Client> clients = new ArrayList<>();
List<User> users = new ArrayList<>();
List<Client> results = new ArrayList<>();

for (Client user : users) {
    for(Client client: clients){
        if(user.getName().equals(client.getUserName())){
            result.add(client);
        }
    }
}

Java Solutions


Solution 1 - Java

Predicate<Client> hasSameNameAsOneUser = 
    c -> users.stream().anyMatch(u -> u.getName().equals(c.getName()));

return clients.stream()
              .filter(hasSameNameAsOneUser)
              .collect(Collectors.toList());

But this is quite inefficient, because it's O(m * n). You'd better create a Set of acceptable names:

Set<String> acceptableNames = 
    users.stream()
         .map(User::getName)
         .collect(Collectors.toSet());

return clients.stream()
              .filter(c -> acceptableNames.contains(c.getName()))
              .collect(Collectors.toList());

Also note that it's not strictly equivalent to the code you have (if it compiled), which adds the same client twice to the list if several users have the same name as the client.

Solution 2 - Java

Look this:

List<Client> result = clients
	.stream()
	.filter(c -> 
		(users.stream().map(User::getName).collect(Collectors.toList())).contains(c.getName()))
		.collect(Collectors.toList());

Solution 3 - Java

I would like share an example to understand the usage of stream().filter

Code Snippet: Sample program to identify even number.

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

public void fetchEvenNumber(){
        List<Integer> numberList = new ArrayList<>();
		numberList.add(10);
		numberList.add(11);
		numberList.add(12);
		numberList.add(13);
		numberList.add(14);
		numberList.add(15);

        List<Integer> evenNumberListObj = numberList.stream().filter(i -> i%2 == 0).collect(Collectors.toList());
		System.out.println(evenNumberListObj);
}

Output will be : [10, 12, 14]

List evenNumberListObj = numberList.stream().filter(i -> i%2 == 0).collect(Collectors.toList());

numberList: it is an ArrayList object contains list of numbers.

java.util.Collection.stream() : stream() will get the stream of collection, which will return the Stream of Integer.

filter: Returns a stream that match the given predicate. i.e based on given condition (i -> i%2 != 0) returns the matching stream.

collect: whatever the stream of Integer filter based in the filter condition, those integer will be put in a list.

Solution 4 - Java

Something like:

clients.stream.filter(c->{
   users.stream.filter(u->u.getName().equals(c.getName()).count()>0
}).collect(Collectors.toList());

This is however not an awfully efficient way to do it. Unless the collections are very small, you will be better of building a set of user names and using that in the condition.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questioneszik.kView Question on Stackoverflow
Solution 1 - JavaJB NizetView Answer on Stackoverflow
Solution 2 - JavaLeoMandrakView Answer on Stackoverflow
Solution 3 - JavaEswaran VenkatesanView Answer on Stackoverflow
Solution 4 - JavadaphshezView Answer on Stackoverflow