简体   繁体   中英

Sort the List based on 2 fields if the first field has more than 1 matching record

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.

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()))

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).thenComparingInt(
         Employee::awards).reversed())
         .findFirst().get();

System.out.println(match);

prints

Employee[id=2, name=Jerry, date=2023-01-19, awards=2]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM