在Java中,自定义排序可以通过多种方式来实现,适用不同场景。以下是几种常用的自定义排序方法以及它们的适用场景:

单词知识

Comparable

Java---自定义排序的多种写法和其适用场景_android


Comparator

Java---自定义排序的多种写法和其适用场景_java_02


compare

Java---自定义排序的多种写法和其适用场景_开发语言_03

1. 实现 Comparable<T> 接口

适用场景

  • 当对象有一个“自然顺序”时,并且你希望在对象的类定义中嵌入排序逻辑时使用。
  • 这种方法适用于希望类具有默认排序规则的情况,例如:String 按字典顺序排序,Integer 按数值大小排序。

写法

class Person implements Comparable<Person> {
    String name;
    int age;

    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 实现compareTo方法,按年龄排序
    @Override
    public int compareTo(Person other) {
        return this.age - other.age; // 升序排序
    }

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

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

        Collections.sort(people);  // 默认排序,按年龄
        people.forEach(System.out::println);
    }
}

优点

  • 简单直接,适合对象有自然顺序。
  • 可以使用 Collections.sort(list)Arrays.sort(array) 进行排序,无需显式传递比较器。

缺点

  • 如果类需要多个排序规则,无法通过 Comparable 实现,需要依赖 Comparator
  • 如果类中排序逻辑经常变动,则每次都要修改类的 compareTo 方法,可能不灵活。

2. 使用 Comparator<T> 接口

适用场景

  • 适用于需要多个排序规则的场景。
  • 可以在不修改类本身的情况下实现不同的排序规则,适合你需要对相同类型的对象按照不同属性排序。

写法

import java.util.Comparator;

class Person {
    String name;
    int age;

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

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

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

        // 自定义Comparator,按名字排序
        Comparator<Person> nameComparator = new Comparator<Person>() {
            @Override
            public int compare(Person p1, Person p2) {
                return p1.name.compareTo(p2.name); // 按名字升序
            }
        };

        // 按名字排序
        Collections.sort(people, nameComparator);
        people.forEach(System.out::println);
    }
}

优点

  • 可以创建多个排序规则,灵活性高。
  • 无需修改对象类本身,可以随时定义新的排序方式。

缺点

  • 相较于 Comparable,需要在每次排序时显式传递 Comparator 对象。

3. 使用 Lambda 表达式和 Comparator.comparing

适用场景

  • 适用于Java 8及以上版本,简化代码,通过Lambda表达式创建 Comparator
  • 在临时或简单排序需求时,避免书写冗长的比较器类。

写法

import java.util.*;

class Person {
    String name;
    int age;

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

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

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

        // 使用Lambda表达式按名字排序
        people.sort(Comparator.comparing(person -> person.name));
        System.out.println("按名字排序:");
        people.forEach(System.out::println);

        // 使用Lambda表达式按年龄排序
        people.sort(Comparator.comparingInt(person -> person.age));
        System.out.println("按年龄排序:");
        people.forEach(System.out::println);
    }
}

优点

  • 简洁、直观,适合简单的排序逻辑。
  • 不需要显式地创建 Comparator 类。
  • 适合一行代码内解决排序问题。

缺点

  • 适用于简单的排序逻辑,复杂排序场景仍需要自定义 Comparator 实现。

总结

  • Comparable:适用于对象有“自然顺序”,并且这种顺序是对象的默认行为。
  • Comparator:适用于需要多个排序规则,或不希望在对象类中嵌入排序逻辑的场景。
  • Lambda & Comparator.comparing:适合简洁、临时的排序需求,尤其是Java 8及以上版本。