Home > other >  Filter in List with condition in the object
Filter in List with condition in the object

Time:11-08

I have a List. Employee, for example:

@Data
@AllArgConstructor
public class Employee {
 
   private string firstName;
   private string last name;
   private domestic salary;
   private LocalDataTime getSalary;

}

The sheet can contain data with the same last name, first name, but different date and salary. Or maybe not. For example.

List<Employee> employee = new ArrayList<>();
Employee one = new Employee("John", "Smith", 10, 2022-09-01);
Employee two = new Employee("John", "Smith", 20, 2022-10-01);
Employee three = new Employee("John", "Smith", 5, 2022-11-01);
Employee four = new Employee("Kelly", "Jones", 12, 2022-03-01);
Employee five = new Employee("Sara", "Kim", 21, 2022-03-01);
Employee six = new Employee("Sara", "Kim", 7, 2022-07-01);

employee.add(one);
employee.add(two);
employee.add(three);
employee.add(four);
employee.add(five);
employee.add(six);

Need for each unique combination of last name and first name, get a data for the last date.

In Out:

"John", "Smith", 5, 2022-11-01

"Kelly", "Jones", 12, 2022-03-01

"Sara", "Kim", 7, 2022-07-01

I'm just starting to learn stream API and dont understand how to filter by a field inside an object for 2 unique other fields.

Is it possible to do so?

CodePudding user response:

You can use collect toMap, the key should be the firstName and lastName, I put them in a list(There are other ways for example concatenate the two attributes, but I don't recommend it), and then use the BinaryOperator to retrieve the max date:

Collection<Employee> response = employee.stream()
        .collect(Collectors.toMap(
               e -> e.getFirstName() e.getLastName(),
               Function.identity(),
               (e1, e2) -> e1.getDate().isAfter(e2.getDate()) ? e1 : e2)).values();

Outputs:

Employee(firstName=John, lastName=Smith, salary=5, date=2022-11-01)
Employee(firstName=Sara, lastName=Kim, salary=7, date=2022-07-01)
Employee(firstName=Kelly, lastName=Jones, salary=12, date=2022-03-01)

CodePudding user response:

My idea is to create hashmap as HashMap<List<String>>,Employee> on top of Stream. Then do merge operation on hashmap. Maps key is list of first_name & last_name:

HashMap<List<String>,Employee> map = 
    employee.stream().collect(HashMap<List<String>, Employee>::new,
                                    (x, y) -> x.merge(List.of(y.getFirstName(), y.getLast_name()), y,
                                            (a, b) -> a.getGetSalary().isAfter(b.getGetSalary()) ? a : b),
                                    (p, q) -> p.putAll(q));

System.out.println(map.values());

This will give you desired result. employee is list which you created in your original post.

  • Related