排序是编程中的一项基础操作,几乎每个程序员都需要在实际工作中处理排序问题。在 Java 中,ArrayList 是最常用的集合之一,而 List 接口提供了非常强大的排序方法。Java 8 引入了新的 List.sort() 方法,使得对 ArrayList 进行排序变得更加简单、直观和功能强大。
Java 中的 List.sort() 方法概述在 Java 8 之前,ArrayList 和 List 的排序通常依赖于 Collections.sort() 方法。Collections.sort() 方法接受一个 List 集合,并使用默认的排序算法(通常是归并排序或快速排序)来对集合中的元素进行排序。然而,在 Java 8 中,List 接口引入了一个新的 sort() 方法,简化了排序操作,并且使得代码更加简洁。
List.sort() 方法签名void sort(Comparator<? super E> c);参数 c:是一个 Comparator 类型的参数,表示排序的比较器。它定义了排序的规则,即如何比较集合中的元素。返回值:该方法返回 void,即它对原始 List 进行排序,并不会创建新的集合。List.sort() 方法与 Collections.sort() 方法的区别List.sort() 方法是 List 接口自带的方法,而 Collections.sort() 方法是 Collections 工具类中的静态方法。虽然两者的功能相似,但 List.sort() 方法更符合面向对象的设计,它是 List 接口的一部分,可以直接在 ArrayList 或其他 List 实现类上调用。而 Collections.sort() 是工具类的方法,需要传入 List 参数。
使用 List.sort() 方法对 ArrayList 进行排序默认排序(自然顺序)如果集合中的元素实现了 Comparable 接口并定义了自然顺序,我们可以直接使用 List.sort() 方法进行排序。Comparable 接口定义了元素的自然顺序,通常是按升序排序。
示例:对 Integer 类型 ArrayList 进行排序import java.util.ArrayList;import java.util.List;public DefaultSortExample { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(5); list.add(2); list.add(8); list.add(1); list.add(3); // 使用 List.sort() 进行默认排序(自然顺序) list.sort(null); // null 表示使用元素的自然顺序进行排序 System.out.println("按自然顺序排序后的列表: " + list); }}输出:
按自然顺序排序后的列表: [1, 2, 3, 5, 8]在这个示例中,Integer 类型已经实现了 Comparable 接口,并定义了自然顺序(按升序排列)。调用 list.sort(null) 时,null 参数表示使用自然顺序进行排序。
按自定义顺序排序如果我们需要按照自定义的排序规则对 ArrayList 进行排序,可以传递一个 Comparator 实例给 List.sort() 方法。Comparator 接口允许我们定义任何排序规则,比如按降序、按字符串长度等。
示例:按降序排序import java.util.ArrayList;import java.util.List;import java.util.Comparator;public CustomSortExample { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(5); list.add(2); list.add(8); list.add(1); list.add(3); // 使用 List.sort() 和自定义 Comparator 进行降序排序 list.sort(Comparator.reverseOrder()); System.out.println("按降序排序后的列表: " + list); }}输出:
按降序排序后的列表: [8, 5, 3, 2, 1]在这个示例中,我们传入了 Comparator.reverseOrder() 作为 Comparator,该方法返回一个降序排列的比较器。
按字符串排序如果 ArrayList 中包含字符串类型的数据,我们可以直接使用 List.sort() 方法对其进行排序。String 类型实现了 Comparable 接口,因此支持自然顺序排序。
示例:对 String 类型 ArrayList 进行排序import java.util.ArrayList;import java.util.List;public StringSortExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Banana"); list.add("Apple"); list.add("Orange"); list.add("Grapes"); // 使用 List.sort() 对字符串进行升序排序 list.sort(null); // null 表示使用自然顺序排序 System.out.println("按字母顺序排序后的字符串列表: " + list); }}输出:
按字母顺序排序后的字符串列表: [Apple, Banana, Grapes, Orange]在这个例子中,String 类型已实现了 Comparable 接口,因此可以直接按字母顺序进行排序。
使用 Lambda 表达式对 ArrayList 进行排序Java 8 引入了 Lambda 表达式,简化了匿名类的使用。通过 Lambda 表达式,我们可以更加简洁地实现 Comparator 比较器,进而对 ArrayList 进行排序。
使用 Lambda 表达式按升序排序示例:对整数列表进行升序排序import java.util.ArrayList;import java.util.List;public LambdaSortExample { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(5); list.add(2); list.add(8); list.add(1); list.add(3); // 使用 Lambda 表达式按升序排序 list.sort((a, b) -> a - b); // 使用 Lambda 表达式自定义升序排序 System.out.println("按升序排序后的列表: " + list); }}输出:
按升序排序后的列表: [1, 2, 3, 5, 8]在此示例中,list.sort((a, b) -> a - b) 使用 Lambda 表达式来定义排序规则,a - b 表示升序排序。
使用 Lambda 表达式按降序排序示例:对整数列表进行降序排序import java.util.ArrayList;import java.util.List;public LambdaReverseSortExample { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(5); list.add(2); list.add(8); list.add(1); list.add(3); // 使用 Lambda 表达式按降序排序 list.sort((a, b) -> b - a); // 使用 Lambda 表达式自定义降序排序 System.out.println("按降序排序后的列表: " + list); }}输出:
按降序排序后的列表: [8, 5, 3, 2, 1]通过 Lambda 表达式 (a, b) -> b - a,我们可以实现降序排序。
对自定义对象使用 List.sort() 方法进行排序在实际应用中,我们经常需要对自定义对象的 ArrayList 进行排序。我们可以通过 Comparator 接口来实现对自定义对象的排序。
定义自定义对象并按属性排序假设我们有一个 Person 类,需要按 age 属性对 Person 对象进行排序。
示例:按 age 升序排序import java.util.ArrayList;import java.util.List;import java.util.Comparator;class Person { String name; int age; Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return name + " (" + age + ")"; }}public PersonSortExample { public static void main(String[] args) { ```java List<Person> list = new ArrayList<>(); list.add(new Person("Alice", 30)); list.add(new Person("Bob", 25)); list.add(new Person("Charlie", 35)); // 使用 List.sort() 和自定义 Comparator 按年龄升序排序 list.sort(Comparator.comparingInt(p -> p.age)); System.out.println("按年龄升序排序后的列表: " + list); }}输出:
按年龄升序排序后的列表: [Bob (25), Alice (30), Charlie (35)]在这个示例中,我们使用 Comparator.comparingInt(p -> p.age) 创建了一个按 age 属性升序排序的比较器。List.sort() 方法接受这个比较器,并对 Person 对象进行排序。
使用 Lambda 表达式进行多重排序我们还可以使用多个排序标准对自定义对象进行排序。通过 Comparator 的 thenComparing() 方法,可以指定次级排序规则。
示例:按 age 升序排序,如果 age 相同,则按 name 字母顺序排序import java.util.ArrayList;import java.util.List;import java.util.Comparator;class Person { String name; int age; Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return name + " (" + age + ")"; }}public MultiSortExample { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person("Alice", 30)); list.add(new Person("Bob", 25)); list.add(new Person("Charlie", 30)); list.add(new Person("David", 25)); // 使用 List.sort() 和多个 Comparator 按年龄升序、姓名字母顺序排序 list.sort(Comparator.comparingInt(Person::getAge) .thenComparing(Person::getName)); System.out.println("按年龄升序和姓名字母顺序排序后的列表: " + list); }}输出:
按年龄升序和姓名字母顺序排序后的列表: [Bob (25), David (25), Alice (30), Charlie (30)]在这个示例中,首先按 age 属性升序排序。如果两个 Person 对象的 age 相同,接着按 name 属性的字母顺序排序。
使用 Stream API 进行排序Java 8 引入了 Stream API,它为排序操作提供了更加灵活和简洁的方式。Stream API 允许我们以函数式的方式对集合进行排序。
使用 Stream 按升序排序示例:使用 Stream 按升序排序import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;public StreamSortExample { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(5); list.add(2); list.add(8); list.add(1); list.add(3); // 使用 Stream API 按升序排序 List<Integer> sortedList = list.stream() .sorted() .collect(Collectors.toList()); System.out.println("按升序排序后的列表: " + sortedList); }}输出:
按升序排序后的列表: [1, 2, 3, 5, 8]在这个示例中,stream() 方法将 list 转换为一个流,sorted() 方法对流进行排序,并使用 collect(Collectors.toList()) 将排序后的结果收集到一个新的 List 中。
使用 Stream 按降序排序示例:使用 Stream 按降序排序import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;import java.util.Comparator;public StreamReverseSortExample { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(5); list.add(2); list.add(8); list.add(1); list.add(3); // 使用 Stream API 按降序排序 List<Integer> sortedList = list.stream() .sorted(Comparator.reverseOrder()) .collect(Collectors.toList()); System.out.println("按降序排序后的列表: " + sortedList); }}输出:
按降序排序后的列表: [8, 5, 3, 2, 1]这里使用 Comparator.reverseOrder() 作为参数传递给 sorted() 方法,来实现按降序排序。
使用 Stream 按自定义对象属性排序Stream API 也可以用于自定义对象的排序。例如,我们可以按 Person 对象的 age 属性排序。
示例:使用 Stream 按 age 升序排序import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;import java.util.Comparator;class Person { String name; int age; Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return name + " (" + age + ")"; }}public StreamSortPersonExample { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person("Alice", 30)); list.add(new Person("Bob", 25)); list.add(new Person("Charlie", 35)); // 使用 Stream API 按年龄升序排序 List<Person> sortedList = list.stream() .sorted(Comparator.comparingInt(p -> p.age)) .collect(Collectors.toList()); System.out.println("按年龄升序排序后的人员列表: " + sortedList); }}输出:
按年龄升序排序后的人员列表: [Bob (25), Alice (30), Charlie (35)]在这个示例中,Comparator.comparingInt(p -> p.age) 用于根据 Person 对象的 age 属性升序排序。