Sunday, June 12, 2022

Java Streams: Filter and fill List from another list object

 1. Example with Predicate

    - Filter list from another list object.
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

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

public class Demo1 {

public static ObjectMapper mapper = new ObjectMapper();

public static void main(String[] args) throws JsonProcessingException {

List<Users> l1 = new ArrayList<>();
List<Users> l2 = new ArrayList<>();

l1.add(new Users("user1", "test1@gmail.com", null));
l1.add(new Users("user2", "test2@gmail.com", 85));

l2.add(new Users("user1", "test1@gmail.com", 35));
l2.add(new Users("user2", "test2@gmail.com", 25));
l2.add(new Users("user3", "test3@gmail.com", 12));

Predicate<Users> InList1P = email -> l1.stream() .anyMatch(e -> e.getEmail().equalsIgnoreCase(email.getEmail()));

List<Users> inList1 = l2.stream().filter(InList1P).collect(Collectors.toList());

System.out.println("inList1 "+ mapper.writeValueAsString(inList1) );

Predicate<Users> notInList1P = email -> l1.stream().noneMatch(e -> e.getEmail().equalsIgnoreCase(email.getEmail()));

List<Users> notInList1 = l2.stream().filter(notInList1P).collect(Collectors.toList());

System.out.println("notInList1 "+ mapper.writeValueAsString(notInList1) );

}


}

Result this:

inList1 [{"name":"user1","email":"test1@gmail.com","age":35},{"name":"user2","email":"test2@gmail.com","age":25}]
notInList1 [{"name":"user3","email":"test3@gmail.com","age":12}]

2. Example without Predicate

    - Filter list from another list object.


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

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

public class Demo1 {

public static ObjectMapper mapper = new ObjectMapper();

public static void main(String[] args) throws JsonProcessingException {

List<Users> l1 = new ArrayList<>();
List<Users> l2 = new ArrayList<>();

l1.add(new Users("user1", "test1@gmail.com", null));
l1.add(new Users("user2", "test2@gmail.com", 85));

l2.add(new Users("user1", "test1@gmail.com", 35));
l2.add(new Users("user2", "test2@gmail.com", 25));
l2.add(new Users("user3", "test3@gmail.com", 12));


List<Users> InList1 =
l2.stream()
.filter(e -> l1.stream()
.map(Users::getEmail)
.anyMatch(email -> email.equalsIgnoreCase(e.getEmail())))
.collect(Collectors.toList());

System.out.println("inList1 "+ mapper.writeValueAsString(InList1) );

List<Users> notInList1 =
l2.stream()
.filter(e -> l1.stream()
.map(Users::getEmail)
.noneMatch(email -> email.equalsIgnoreCase(e.getEmail())))
.collect(Collectors.toList());

System.out.println("notInList1 "+ mapper.writeValueAsString(notInList1) );

}

}

Result this:

inList1 [{"name":"user1","email":"test1@gmail.com","age":35},{"name":"user2","email":"test2@gmail.com","age":25}]
notInList1 [{"name":"user3","email":"test3@gmail.com","age":12}]

3. Example count condition

Sometimes is necessary to distinct by key value on the list for e.g. by email in my case. and I share this predicate function is very useful. The original function here.

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

  •      count == 1 then return value between two list
  •      count <   1 then return value doesn't exist in second list
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class Demo1 {

public static ObjectMapper mapper = new ObjectMapper();

public static void main(String[] args) throws JsonProcessingException {

List<Users> l1 = new ArrayList<>();
List<Users> l2 = new ArrayList<>();

l1.add(new Users("user1", "test1@gmail.com", null));
l1.add(new Users("user2", "test2@gmail.com", 85));
l1.add(new Users("user3", "test3@gmail.com", 10));

l2.add(new Users("user1", "test1@gmail.com", 35));
l2.add(new Users("user2", "test2@gmail.com", 25));
l2.add(new Users("user2", "test2@gmail.com", 25));


List<Users> c1 = l1
.stream()
.filter(e -> (
(l2.stream()
.filter(distinctByKey(Users::getEmail))
)
.filter(d -> d.getEmail().compareTo(e.getEmail())==0)
.count())==1)
.collect(Collectors.toList());

System.out.println("c1 "+ mapper.writeValueAsString(c1) );

List<Users> c2 = l1
.stream()
.filter(e -> (
(l2.stream()
.filter(distinctByKey(Users::getEmail))
)
.filter(d -> d.getEmail().compareTo(e.getEmail())==0)
.count()) < 1)
.collect(Collectors.toList());

System.out.println("c2 "+ mapper.writeValueAsString(c2) );

}

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

}

Result this:

c1 [{"name":"user1","email":"test1@gmail.com","age":null},{"name":"user2","email":"test2@gmail.com","age":85}]
c2 [{"name":"user3","email":"test3@gmail.com","age":10}]

4. Fill list from another list object by condition

The original example here.

In this scenario in the first list any age attributes is null then we copy value from second list.

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;

public class Demo1 {

public static ObjectMapper mapper = new ObjectMapper();

public static void main(String[] args) throws JsonProcessingException {

List<Users> l1 = new ArrayList<>();
List<Users> l2 = new ArrayList<>();

l1.add(new Users("user1", "test1@gmail.com", null));
l1.add(new Users("user2", "test2@gmail.com", 85));
l1.add(new Users("user3", "test3@gmail.com", null));
l1.add(new Users("user4", "test4@gmail.com", 10));
l1.add(new Users("user5", "test5@gmail.com", null));
l1.add(new Users("user6", "test6@gmail.com", 17));

l2.add(new Users("user1", "test1@gmail.com", 35));
l2.add(new Users("user2", "test2@gmail.com", 25));
l2.add(new Users("user3", "test3@gmail.com", 12));
l2.add(new Users("user5", "test5@gmail.com", 14));
l2.add(new Users("user5", "test5@gmail.com", 14));
l2.add(new Users("user8", "test8@gmail.com", 23));
l2.add(new Users("user9", "test9@gmail.com", 9));

List<Users> newList1 = l1.stream().collect(ArrayList::new, (list, obj) -> {

Optional<Users> match = l2.stream().filter(s -> s.getEmail().equalsIgnoreCase(obj.getEmail())).findAny();

if (match.isPresent()) {
if (obj.getAge() == null) {
obj.setAge(match.get().getAge());
}
list.add(obj);
} else {
list.add(obj);
}
}, ArrayList::addAll);

System.out.println("newList1 "+ mapper.writeValueAsString(newList1) );

// by distinct email list l2
List<Users> newList2 = l1.stream().collect(ArrayList::new, (list, obj) -> {

Optional<Users> match = l2.stream().filter(distinctByKey(Users::getEmail))
.filter(s -> s.getEmail().equalsIgnoreCase(obj.getEmail())).findAny();

if (match.isPresent()) {
if (obj.getAge() == null) {
obj.setAge(match.get().getAge());
}
list.add(obj);
} else {
list.add(obj);
}
}, ArrayList::addAll);

System.out.println("newList2 "+ mapper.writeValueAsString(newList2) );
}

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}

Result this:
newList1 [{"name":"user1","email":"test1@gmail.com","age":35},{"name":"user2","email":"test2@gmail.com","age":85},
{"name":"user3","email":"test3@gmail.com","age":12},{"name":"user4","email":"test4@gmail.com","age":10},
{"name":"user5","email":"test5@gmail.com","age":14},{"name":"user6","email":"test6@gmail.com","age":17}]
newList2 [{"name":"user1","email":"test1@gmail.com","age":35},{"name":"user2","email":"test2@gmail.com","age":85},
{"name":"user3","email":"test3@gmail.com","age":12},{"name":"user4","email":"test4@gmail.com","age":10},
{"name":"user5","email":"test5@gmail.com","age":14},{"name":"user6","email":"test6@gmail.com","age":17}]

4. Dto class

public class Users {

private String name;
private String email;
private Integer age;

public Users() {
}

public Users(String name, String email, Integer age) {
this.name = name;
this.email = email;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

}

        







References:

https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html
https://mkyong.com/java8/java-8-predicate-examples/
https://www.baeldung.com/java-streams-find-list-items
https://www.geeksforgeeks.org/java-8-predicate-with-examples/
https://www.codegrepper.com/code-examples/java/java+find+if+element+of+list+in+present+in+another+list
https://stackoverflow.com/questions/66561141/create-list-of-objects-from-another-list-by-using-java8-stream
https://stackoverflow.com/questions/27822703/java-8-stream-filtering-value-of-list-in-a-list





































































































































No comments:

Post a Comment

Virtual Threads in Java 21: Simplified Concurrency for Modern Applications

  With Java 21, Virtual Threads have redefined how we approach concurrency, offering a lightweight and efficient way to handle parallel and ...