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.