I have a table with the below info
Id | Name | EmpDate | AwardsReceived |
---|---|---|---|
1 | Tom | 1/19/2023 | 1 |
2 | Jerry | 1/19/2023 | 2 |
3 | Peppa | 1/18/2023 | 1 |
Consider I have the above data in a list EmployeeList. I wanted to sort the list based on Empdate first and if there is more than 1 employee with the same latest date, then I want to sort them with the awardsReceived and get the latest one from the list.
So , from the above data, I want to get Jerry using java8 streams.
I have tried the below code but, its not working as expected.
Optional <Employee> employee = employeeList.stream() .sorted(Comparator.comparing(Employee::getEmpDate).reversed()) .sorted(Comparator.comparing(Employee::getAwardsReceived).reversed()).findFirst();
Please suggest the valid approach.
CodePudding user response:
You can achieve it using the below sample code. Let me know if it doesn't works.
employeeList.stream()
.sorted((e1, e2) -> e2.getEmpDate().compareTo(e1.getEmpDate()))
.sorted((e1, e2) -> Integer.compare(e2.getAwardsReceived(), e1.getAwardsReceived()))
CodePudding user response:
You should be using LocalDate for the dates since string dates will not compare chronologically but lexically. But here is how you would accomplish it.
I am using a record, which is an immutable class so either would work. I am also converting the date to LocalDate
record Employee(int id, String name, LocalDate date, int awards) {
public Employee (int id, String name, String date, int awards) {
this(id, name, LocalDate.parse(date,
DateTimeFormatter.ofPattern("M/dd/yyyy")), awards);
}
}
List<Employee> employeeList = List.of(
new Employee(1, "Tom", "1/19/2023", 1),
new Employee(4, "Mary", "1/19/2023", 1),
new Employee(5, "Bob", "1/14/2023", 2),
new Employee(2, "Jerry", "1/19/2023", 2),
new Employee(3, "Peppa", "1/13/2023", 3));
- First compare on the employee date using a Comparator. Most recent dates would be sorted first as their natural order.
- if two are equal, then sort on the employee awards in reverse order (to get the max awards first).
- the use findFirst to get the first occurrence and retrieve it from the Optional
Employee match = employeeList.stream()
.sorted(Comparator.comparing(Employee::date).thenComparing(
Employee::awards).reversed())
.findFirst().get();
System.out.println(match);
prints
Employee[id=2, name=Jerry, date=2023-01-19, awards=2]