on it road .com

Java 比较器示例

Java排序对象列表

按姓名对员工列表进行排序

ArrayList<Employee> list = new ArrayList<>();

list.add(new Employee(22l, "Jamez", LocalDate.now()));
list.add(new Employee(30l, "Bob", LocalDate.now()));
list.add(new Employee(18l, "JackLi", LocalDate.now()));
list.add(new Employee(5l, "Tomm", LocalDate.now()));
list.add(new Employee(600l, "Lucie", LocalDate.now()));
//Sort in reverse natural order
Collections.sort(list, new NameSorter());
System.out.println(list);

输出:

[
	Employee [id=18, name=JackLi, dob=2018-10-30], 
	Employee [id=30, name=Bob, dob=2018-10-30], 
	Employee [id=600, name=Lucie, dob=2018-10-30], 
	Employee [id=5, name=Tomm, dob=2018-10-30], 
	Employee [id=22, name=Jamez, dob=2018-10-30]
]

按多个字段排序对象列表

对多个字段的员工列表进行排序:

ArrayList<Employee> list = new ArrayList<>();

list.add(new Employee(22l, "Jamez", LocalDate.now()));
list.add(new Employee(30l, "Jamez", LocalDate.now()));
list.add(new Employee(18l, "JackLi", LocalDate.now()));
list.add(new Employee(5l, "Jamez", LocalDate.now()));
list.add(new Employee(600l, "Lucie", LocalDate.now()));
Comparator<Employee> groupByComparator = Comparator.comparing(Employee::getName)
                                        .thenComparing(Employee::getDob)
                                        .thenComparing(Employee::getId);
Collections.sort(list, groupByComparator);
System.out.println(list);

输出:

[
	Employee [id=18, name=JackLi, dob=2018-10-30], 
	Employee [id=600, name=Lucie, dob=2018-10-30], 
	Employee [id=5, name=Jamez, dob=2018-10-30], 
	Employee [id=22, name=Jamez, dob=2018-10-30], 
	Employee [id=30, name=Jamez, dob=2018-10-30]]
Java Comparator 接口

Java Comparator 接口用于根据自定义顺序对数组或者对象列表进行排序。

元素的自定义排序是通过在对象中实现 Comparator.compare() 方法来实现的。

Java Comparator接口对可能没有自然排序的对象强加总排序。

在实际应用中,我们可能希望按员工的名字、出生日期或者任何其他此类标准对员工列表进行排序。

我们可以在以下情况下使用 Comparator 接口。

  • 对数组或者对象列表进行排序,但不是按自然顺序排序。
  • 对我们无法修改对象的源代码的对象数组或者列表进行排序以实现 Comparable 接口。
  • 对不同字段上的相同对象列表或者数组进行排序。
  • 在不同字段上的对象列表或者数组上按排序使用分组。

Comparator.compare()

为了启用对象的总排序,我们需要创建实现 Comparator 接口的类。
然后我们需要覆盖它的 compare(T o1, T o2) 方法。

它比较它的两个顺序参数。
当第一个参数小于、等于或者大于第二个参数时,它返回一个负整数、零或者正整数。

实现者还必须确保关系是可传递的:((compare(x, y)&gt;0) &amp;&amp; (compare(y, z)&gt;0))意味着 compare(x, z)&gt;0

import java.time.LocalDate;
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;
    private String name;
    private LocalDate dob;
    //Getters and Setters
    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", dob=" + dob + "]";
    }
}

对于上面的类,可以通过创建像下面这样的 Comparator 来强制按员工姓名排序。

import java.util.Comparator;
public class NameSorter implements Comparator<Employee>
{
    @Override
    public int compare(Employee e1, Employee e2) {
        return e1.getName().compareToIgnoreCase( e2.getName() );
    }
}

Collections.sort() 和 Arrays.sort()

  • 使用 Collections.sort(list, Comparator) 方法按提供的比较器实例强加的顺序对对象列表进行排序。
  • 使用 Arrays.sort(array, Comparator) 方法按提供的比较器实例强加的顺序对对象数组进行排序。

Collections.comparing()

此实用程序方法接受一个为类提取排序键的函数。
这本质上是一个字段,类对象将在该字段上进行排序。

//Order by name
Comparator.comparing(Employee::getName);
//Order by name in reverse order
Comparator.comparing(Employee::getName).reversed();
//Order by id field
Comparator.comparing(Employee::getId);
//Order by employee age
Comparator.comparing(Employee::getDate);

Collections.thenComparing()

此实用方法用于按排序分组。
使用这种方法,我们可以链接多个比较器来对多个字段上的对象列表或者数组进行排序。

它与 SQL GROUP BY 子句对不同字段上的行进行排序非常相似。

//Order by name and then by age
Comparator.comparing(Employee::getName)
			.thenComparing(Employee::getDob);
//Order by name -> date of birth -> id 
Comparator.comparing(Employee::getName)
			.thenComparing(Employee::getDob)
			.thenComparing(Employee::getId);

Collections.reverseOrder()

此实用程序方法返回一个比较器,该比较器对实现 Comparable 接口的对象集合进行自然排序或者总排序的反向。

//Reverse of natural order as specified in 
//Comparable interface's compareTo() method 
Comparator.reversed();
//Reverse of order by name
Comparator.comparing(Employee::getName).reversed();
日期:2020-09-17 00:09:47 来源:oir作者:oir