java Comparator 多个字段比较

it2023-07-29  67

List 中元素需要排序时,需要比较元素值,当元素是复杂对象时,有时需要根据多个字段进行排序。

package com.example.demo.domain; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; @Getter @ToString @NoArgsConstructor public class Employee { private Long id; private String name; public Employee(Long id, String name) { this.id = id ; this.name = name; } }

先看下基础数据类型的比较:

@Test public void comparator_test(){ // int 类型的比较结果是 1、0、-1 三者之一。 System.out.println( Integer.compare(2,1)); // 1 System.out.println( Integer.compare(2,2)); // 0 System.out.println( Integer.compare(2,4)); // -1 // String 类型的比较结果是 两个字符串长度的差值,左边小为负,左边大为正。 System.out.println("".compareTo("abc")); // -3 System.out.println("abc".compareTo("")); // 3 System.out.println("abc".compareTo("a")); // 2 System.out.println("ab".compareTo("abc")); // -1 System.out.println("abc".compareTo("abc")); // 0 // 将 String 类型的比较结果规约成 1、0、-1 三者之一。 System.out.println(Integer.compare("".compareTo("abc"),0)); // -1 System.out.println(Integer.compare("abc".compareTo(""),0)); // 1 System.out.println(Integer.compare("abc".compareTo("a"),0)); // 1 System.out.println(Integer.compare("ab".compareTo("abc"),0)); // -1 System.out.println(Integer.compare("abc".compareTo("abc"),0)); // 0 }

看一种多字段比较的方式:

package com.example.demo.domain; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.junit.jupiter.api.Test; class EmployeeTest { @Test public void should_sort_employees_with_id_and_name(){ List<Employee> employees = new ArrayList<Employee>(){{ add(new Employee(3L,"name-3")); add(new Employee(1L,"name-1")); add(new Employee(2L,"name-2")); add(new Employee(2L,"name-4")); add(new Employee(3L,"name-1")); add(new Employee(1L,"name-6")); add(new Employee(2L,"name-0")); add(new Employee(3L,"name-2")); }}; System.out.println(employees); employees.sort(new EmployeeComparator()); System.out.println(employees); } } // 假定 id 比较的优先级高于 name。 class EmployeeComparator implements Comparator<Employee>{ @Override public int compare(Employee o1, Employee o2) { int idCompareResult = Integer.compare(o1.getId().compareTo(o2.getId()),0); int nameCompareResult = o1.getName().compareTo(o2.getName()); // 将每个字段的比较结果按优先级加权求和,就是两个对象的比较结果了。 int compareResult = idCompareResult * 10 + nameCompareResult; // 将最终结果规约成 1、0、-1 三者中的一个。 return Integer.compare(compareResult,0); } }

结果:

[Employee(id=3, name=name-3), Employee(id=1, name=name-1), Employee(id=2, name=name-2), Employee(id=2, name=name-4), Employee(id=3, name=name-1), Employee(id=1, name=name-6), Employee(id=2, name=name-0), Employee(id=3, name=name-2)] [Employee(id=1, name=name-1), Employee(id=1, name=name-6), Employee(id=2, name=name-0), Employee(id=2, name=name-2), Employee(id=2, name=name-4), Employee(id=3, name=name-1), Employee(id=3, name=name-2), Employee(id=3, name=name-3)]
最新回复(0)