杰瑞科技汇

Java ArrayList如何排序?

使用 Collections.sort() (适用于基本数据类型和自定义对象)

这是最传统、最简单的方法,适用于 Java 8 之前的环境,现在依然非常常用。

Java ArrayList如何排序?-图1
(图片来源网络,侵删)

a) 排序基本数据类型的包装类 (如 Integer, String)

Collections.sort() 方法可以直接对 ArrayList 中的元素进行自然排序(升序)。

示例:排序 Integer 类型的 ArrayList

import java.util.ArrayList;
import java.util.Collections;
public class SortArrayListExample {
    public static void main(String[] args) {
        // 1. 创建一个 ArrayList
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(1);
        numbers.add(8);
        numbers.add(3);
        numbers.add(9);
        System.out.println("排序前: " + numbers);
        // 2. 使用 Collections.sort() 进行升序排序
        Collections.sort(numbers);
        System.out.println("升序排序后: " + numbers);
    }
}

输出:

排序前: [5, 1, 8, 3, 9]
升序排序后: [1, 3, 5, 8, 9]

示例:排序 String 类型的 ArrayList

Java ArrayList如何排序?-图2
(图片来源网络,侵删)

字符串会按照字典序(lexicographical order)进行排序。

import java.util.ArrayList;
import java.util.Collections;
public class SortStringArrayList {
    public static void main(String[] args) {
        ArrayList<String> fruits = new ArrayList<>();
        fruits.add("Banana");
        fruits.add("Apple");
        fruits.add("Orange");
        fruits.add("Grape");
        System.out.println("排序前: " + fruits);
        // 使用 Collections.sort() 进行排序
        Collections.sort(fruits);
        System.out.println("排序后: " + fruits);
    }
}

输出:

排序前: [Banana, Apple, Orange, Grape]
排序后: [Apple, Banana, Grape, Orange]

b) 降序排序

如果需要降序排序,可以使用 Collections.reverseOrder()

import java.util.ArrayList;
import java.util.Collections;
public class SortDescending {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(1);
        numbers.add(8);
        numbers.add(3);
        System.out.println("排序前: " + numbers);
        // 使用 Collections.sort() 和 Collections.reverseOrder() 进行降序排序
        Collections.sort(numbers, Collections.reverseOrder());
        System.out.println("降序排序后: " + numbers);
    }
}

输出:

Java ArrayList如何排序?-图3
(图片来源网络,侵删)
排序前: [5, 1, 8, 3]
降序排序后: [8, 5, 3, 1]

使用 List.sort() 方法 (Java 8+)

从 Java 8 开始,List 接口本身增加了一个 sort() 方法,这使得代码更加面向对象,无需再导入 Collections 类。

它接受一个 Comparator 对象作为参数。

a) 升序排序 (使用 Comparator.naturalOrder())

对于实现了 Comparable 接口的对象(如 Integer, String),可以使用 Comparator.naturalOrder() 来表示自然排序。

import java.util.ArrayList;
import java.util.Comparator;
public class ListSortExample {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(1);
        numbers.add(8);
        System.out.println("排序前: " + numbers);
        // 使用 List.sort() 和 Comparator.naturalOrder() 进行升序排序
        numbers.sort(Comparator.naturalOrder());
        System.out.println("升序排序后: " + numbers);
    }
}

b) 降序排序 (使用 Comparator.reverseOrder())

同样,降序排序可以使用 Comparator.reverseOrder()

// ... (同上)
numbers.sort(Comparator.reverseOrder());
// ...

对自定义对象进行排序

这是最常见也最重要的场景,当你有一个 ArrayList 存放自定义类的对象时,你必须告诉 Java 根据什么规则来排序。

有两种方式:

让自定义类实现 Comparable 接口

这种方式定义了类的“自然排序”规则,一旦实现,任何使用这个类的 Collections.sort()List.sort() 都会默认使用这个规则。

步骤:

  1. 在你的自定义类中实现 Comparable<T> 接口(T 是你的类名)。
  2. 重写 compareTo(T other) 方法。
    • 返回一个负整数 (this < other)
    • 返回零 (this == other)
    • 返回一个正整数 (this > other)

示例:按 age 排序 Person 对象

import java.util.ArrayList;
import java.util.Collections;
// 1. Person 类实现 Comparable 接口
class Person implements Comparable<Person> {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public String getName() {
        return name;
    }
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
    // 2. 重写 compareTo 方法,按年龄排序
    @Override
    public int compareTo(Person otherPerson) {
        // this.age < otherPerson.age  返回负数
        // this.age == otherPerson.age 返回 0
        // this.age > otherPerson.age  返回正数
        return this.age - otherPerson.age;
    }
}
public class SortCustomObject {
    public static void main(String[] args) {
        ArrayList<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30));
        people.add(new Person("Bob", 25));
        people.add(new Person("Charlie", 35));
        people.add(new Person("David", 25));
        System.out.println("排序前: " + people);
        // 3. 直接调用 Collections.sort(),它会自动使用 compareTo 方法
        Collections.sort(people);
        System.out.println("按年龄升序排序后: " + people);
    }
}

输出:

排序前: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=35}, Person{name='David', age=25}]
按年龄升序排序后: [Person{name='Bob', age=25}, Person{name='David', age=25}, Person{name='Alice', age=30}, Person{name='Charlie', age=35}]

注意:Bob 和 David 年龄相同,他们的相对顺序在排序后可能保持不变(稳定排序)。

使用 Comparator (更灵活)

如果你不想修改类的定义,或者一个类需要多种排序方式,Comparator 是更好的选择,你可以在需要排序时动态创建比较规则。

方法:

  • 使用 Comparator.comparing() 来创建 Comparator
  • 可以链式调用 .thenComparing() 来实现多条件排序。

示例:按 name 排序,name 相同则按 age 排序

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
class Person {
    private String name;
    private int age;
    // ... (构造方法, getter, toString 同上)
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public int getAge() { return age; }
    public String getName() { return name; }
    @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; }
}
public class SortWithComparator {
    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));
        people.add(new Person("Bob", 20)); // 另一个 Bob
        System.out.println("排序前: " + people);
        // 使用 Comparator.comparing() 创建比较器
        // 先按 name 排序,name 相同,再按 age 排序
        Comparator<Person> byNameThenByAge = Comparator
                .comparing(Person::getName) // 按名字比较
                .thenComparing(Person::getAge); // 如果名字相同,再按年龄比较
        // 使用 List.sort() 方法传入比较器
        people.sort(byNameThenByAge);
        System.out.println("按姓名和年龄排序后: " + people);
    }
}

输出:

排序前: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=35}, Person{name='Bob', age=20}]
按姓名和年龄排序后: [Person{name='Alice', age=30}, Person{name='Bob', age=20}, Person{name='Bob', age=25}, Person{name='Charlie', age=35}]

使用 Java 8 Stream 进行排序

Stream 提供了一种函数式的方式来处理集合,排序是其中之一,这种方法不会修改原始 ArrayList,而是返回一个新的已排序的 Stream,你需要将其收集回一个 List

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class StreamSortExample {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(1);
        numbers.add(8);
        numbers.add(3);
        System.out.println("原始列表: " + numbers);
        // 使用 Stream 进行升序排序,并收集到新的 List 中
        List<Integer> sortedNumbers = numbers.stream()
                                             .sorted() // 默认自然排序
                                             .collect(Collectors.toList());
        System.out.println("Stream升序排序后: " + sortedNumbers);
        // 使用 Stream 进行降序排序
        List<Integer> sortedDescending = numbers.stream()
                                                .sorted(Comparator.reverseOrder())
                                                .collect(Collectors.toList());
        System.out.println("Stream降序排序后: " + sortedDescending);
    }
}

输出:

原始列表: [5, 1, 8, 3]
Stream升序排序后: [1, 3, 5, 8]
Stream降序排序后: [8, 5, 3, 1]

总结与选择

方法 适用场景 特点
Collections.sort(list) Java 8 之前,或习惯传统写法 简单直接,是静态工具方法。
list.sort(comparator) Java 8+,推荐 更面向对象,是 List 接口的方法。
Comparable 接口 定义类的“自然排序”规则 侵入式,一旦定义,排序规则固定,适合一个类只有一种主要排序逻辑的场景。
Comparator 接口 需要多种排序方式,或不想修改类 非侵入式,非常灵活,可以在任何需要的时候定义新的排序规则。推荐使用
Stream.sorted() 函数式编程风格,需要链式操作 不修改原列表,返回新列表,适合在流处理管道中进行排序。

最佳实践建议:

  • 对于自定义对象排序,强烈推荐使用 Comparator,它更灵活,不污染你的类定义,并且可以轻松实现多条件排序。
  • 如果只是对基本数据类型或字符串进行简单的升/降序排序,List.sort(Comparator.naturalOrder())List.sort(Comparator.reverseOrder()) 是非常简洁的选择。
  • 如果你的排序逻辑是复杂的多步操作,或者你正在使用函数式编程范式,Stream 是一个很好的选择。
分享:
扫描分享到社交APP
上一篇
下一篇