Java Comparator多级排序

在Java中,我们经常需要对一组对象进行排序。通常情况下,我们可以使用 Comparable 接口来实现对象的自然排序。但是,有时候我们需要根据不同的排序规则来对对象进行排序,这就需要使用 Comparator 接口了。

Comparator 接口允许我们定义自定义的比较规则,从而实现多级排序。本文将介绍如何使用 Comparator 接口进行多级排序,并提供一些示例代码来帮助你理解。

Comparator 接口概述

Comparator 接口是 Java 中的一个函数式接口,它定义了两个方法:

  1. compare(T o1, T o2):比较两个对象的大小。如果返回值小于 0,表示 o1 小于 o2;如果返回值大于 0,表示 o1 大于 o2;如果返回值等于 0,表示 o1 等于 o2
  2. equals(Object obj):判断当前对象是否等于指定对象。

多级排序示例

假设我们有一个 Person 类,它包含姓名、年龄和身高三个属性。现在我们需要根据不同的排序规则来对 Person 对象进行排序。

首先,我们定义一个 Person 类:

public class Person {
    private String name;
    private int age;
    private double height;

    public Person(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    // 省略 getter 和 setter 方法

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}

接下来,我们需要定义多个比较器来实现多级排序。假设我们需要按照以下顺序对 Person 对象进行排序:先按照年龄升序排序,如果年龄相同则按照身高降序排序,如果身高也相同则按照姓名排序。

我们可以定义一个 PersonComparator 类来实现这个多级排序的逻辑:

import java.util.Comparator;

public class PersonComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        // 按照年龄升序排序
        if (p1.getAge() < p2.getAge()) {
            return -1;
        } else if (p1.getAge() > p2.getAge()) {
            return 1;
        }
        
        // 年龄相同,按照身高降序排序
        if (p1.getHeight() > p2.getHeight()) {
            return -1;
        } else if (p1.getHeight() < p2.getHeight()) {
            return 1;
        }

        // 年龄和身高相同,按照姓名排序
        return p1.getName().compareTo(p2.getName());
    }
}

使用了 Comparator 接口后,我们可以通过调用 Collections.sort() 方法来对 List 中的对象进行排序:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 25, 165.0));
        people.add(new Person("Bob", 30, 175.0));
        people.add(new Person("Charlie", 20, 170.0));
        people.add(new Person("David", 25, 170.0));

        // 使用自定义的比较器进行多级排序
        Collections.sort(people, new PersonComparator());

        for (Person person : people) {
            System.out.println(person);
        }
    }
}

输出结果为:

Person{name='Charlie', age=20, height=170.0}
Person{name='David', age=25, height=170.0}
Person{name='Alice', age=25, height=165.0}
Person{name='Bob', age=30, height=175.0}

序列图

下面是一个使用 Comparator 进行多级排序的序列图示例:

sequenceDiagram
    participant Client
    participant Comparator
    participant Collections
    participant List
    participant Person
    Client->>List: add(person1)
    Client->>List: add(person2)
    Client->>List: add(person3)
    Client->>Collections