Java Collections.sort 方法
上次修改时间:2025 年 4 月 20 日
Collections.sort
方法是 Java 的 java.util.Collections
类中的一个实用方法。它提供了对 List 中的元素进行排序的功能。该方法有两种变体:一种根据自然顺序排序,另一种使用 Comparator。
排序是编程中的一项基本操作。Collections.sort 方法为 List 提供了高效的排序算法。它使用一种改进的归并排序算法,提供 n log(n) 的性能。
Collections.sort 概述
Collections.sort 方法将指定的列表按升序排序。元素必须实现 Comparable 接口才能进行自然排序。或者,您可以提供一个 Comparator 用于自定义排序。
排序是稳定的,这意味着相等的元素不会被重新排序。该方法在原地操作,修改原始列表。对于不可变列表,它会抛出 UnsupportedOperationException。
使用 Collections.sort 的基本排序
此示例演示了 Collections.sort 的最简单用法。我们创建一个 String 列表并按自然顺序对它们进行排序。String 实现了 Comparable 接口,因此不需要额外的配置。
package com.zetcode; import java.util.Arrays; import java.util.Collections; import java.util.List; public class BasicSortExample { public static void main(String[] args) { List<String> names = Arrays.asList( "John", "Adam", "Jane", "Peter", "Mary" ); System.out.println("Before sorting: " + names); Collections.sort(names); System.out.println("After sorting: " + names); } }
此代码创建一个名称列表并按字母顺序对其进行排序。输出显示了排序前后的列表。由于它使用 String 的自然顺序,因此排序区分大小写。
Collections.sort 方法会修改原始列表。如果您需要保留原始顺序,请在排序之前创建一个副本。
排序自定义对象
要在 Java 中对自定义对象进行排序,您可以实现 Comparable
接口以进行自然排序,或者提供自定义 Comparator
以进行特定排序逻辑。此示例演示了 Person
记录实现 Comparable
,以根据 name
字段定义自然顺序。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; record Person(String name, int age) implements Comparable<Person> { @Override public int compareTo(Person other) { return this.name.compareTo(other.name); } } public class CustomObjectSort { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Adam", 30)); people.add(new Person("Jane", 22)); System.out.println("Before sorting: " + people); Collections.sort(people); System.out.println("After sorting: " + people); } }
Person
记录重写了 compareTo
方法,委托给 String
的 compareTo
方法以按字母顺序对名称进行排序。Collections.sort
方法使用此自然顺序按名称升序排列 Person
对象。
输出显示了按名称字母顺序排序的列表,如自然顺序所定义。当对象具有固有的或“默认”排序顺序时,实现 Comparable
接口是一种清晰有效的做法,这使得代码更易于理解和维护。
使用 Comparator 排序
当您无法修改类或需要不同的排序顺序时,请使用 Comparator
。此示例演示了如何使用 Comparator 按年龄对 Person 进行排序。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; record Person(String name, int age) {} public class ComparatorSort { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Adam", 30)); people.add(new Person("Jane", 22)); System.out.println("Original order: " + people); // Sort by age using Comparator Collections.sort(people, Comparator.comparingInt(Person::age)); System.out.println("Sorted by age: " + people); } }
此示例使用一个比较器按年龄排序,使用方法引用 Comparator.comparingInt(Person::age)
创建。与匿名实现不同,这种方法利用了现代 Java 函数式编程,以实现简洁易读的代码。通过直接引用 age
字段,比较被简化,并避免了手动实现 compare
方法。
输出显示了按年龄升序排序的列表。这演示了比较器的灵活性,比较器特别适用于自定义排序逻辑,包括处理多个标准或动态排序。
用于排序的 Lambda 表达式
Lambda 表达式简化了 Comparator
的创建。此示例演示了如何将 lambda 与 Collections.sort
一起使用以实现简洁的代码。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; record Person(String name, int age) {} public class LambdaSort { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Adam", 30)); people.add(new Person("Jane", 22)); System.out.println("Original order: " + people); // Sort by name using lambda Collections.sort(people, Comparator.comparing(Person::name)); System.out.println("Sorted by name: " + people); // Sort by age using lambda Collections.sort(people, Comparator.comparingInt(Person::age)); System.out.println("Sorted by age: " + people); } }
Lambda 表达式使 Comparator
代码更加简洁。第一个排序使用 lambda 比较名称。第二个排序比较年龄,每行代码只需要一行。
输出演示了两种排序顺序。当您需要在应用程序的不同部分中使用多个排序标准时,lambda 表达式特别有用。
反向排序
Collections.sort
可以使用 Comparator.reverseOrder
或 Collections.reverseOrder
按相反的顺序排序。此示例演示了这两种方法。
package com.zetcode; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class ReverseSort { public static void main(String[] args) { List<String> names = Arrays.asList( "John", "Adam", "Jane", "Peter", "Mary" ); System.out.println("Original order: " + names); // Natural order sort Collections.sort(names); System.out.println("Natural order: " + names); // Reverse order using reverseOrder() Collections.sort(names, Collections.reverseOrder()); System.out.println("Reverse order: " + names); // Alternative reverse sort names.sort(Comparator.reverseOrder()); System.out.println("Alternative reverse: " + names); } }
此示例首先按自然顺序对名称进行排序,然后反转顺序。Collections.reverseOrder
返回一个 Comparator
,它会反转自然顺序。另一种方法是直接使用 List 的 sort 方法。
输出显示了每个排序步骤。反向排序对于以降序显示数据(例如首先显示最高分数)很有用。
使用多个条件的排序
对于具有多个字段的复杂排序,请使用 Comparator 链。此示例使用 thenComparing 按名称然后按年龄对 Person 进行排序。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; record Person(String name, int age) { } public class MultiCriteriaSort { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Adam", 30)); people.add(new Person("Jane", 22)); people.add(new Person("Adam", 25)); System.out.println("Original order: " + people); // Sort by name then age Collections.sort(people, Comparator .comparing(Person::name) .thenComparingInt(Person::age) ); System.out.println("Sorted by name then age: " + people); } }
此示例使用 Java 8 的 Comparator.comparing 和 thenComparing 方法。首先,它按名称排序,然后按年龄对具有相同名称的人进行排序。方法引用使代码更具可读性。
输出显示了主要按名称排序,其次按年龄排序的列表。当处理复杂的排序要求时,此技术至关重要。
不区分大小写的排序
对于不区分大小写的字符串排序,请使用 String.CASE_INSENSITIVE_ORDER 或自定义 Comparator。此示例演示了这两种方法。
package com.zetcode; import java.util.Arrays; import java.util.Collections; import java.util.List; public class CaseInsensitiveSort { public static void main(String[] args) { List<String> words = Arrays.asList( "apple", "Orange", "banana", "PEAR", "Grape" ); System.out.println("Original order: " + words); // Case-sensitive sort (natural order) Collections.sort(words); System.out.println("Case-sensitive sort: " + words); // Case-insensitive sort using String.CASE_INSENSITIVE_ORDER Collections.sort(words, String.CASE_INSENSITIVE_ORDER); System.out.println("Case-insensitive sort: " + words); // Alternative using lambda Collections.sort(words, String::compareToIgnoreCase); System.out.println("Lambda case-insensitive: " + words); } }
该示例首先显示区分大小写的排序,其中大写字母排在小写字母之前。然后它演示了使用 String 的内置 Comparator 和带有 compareToIgnoreCase 的 lambda 的不区分大小写的排序。
输出清楚地显示了区分大小写和不区分大小写的排序之间的区别。不区分大小写的排序通常是用户在应用程序中期望的。
来源
在本文中,我们深入探讨了 Java 的 Collections.sort 方法。我们涵盖了基本排序、自定义对象、Comparators、lambdas、反向排序、多条件排序和大小写敏感性。掌握这些技术对于有效的 Java 开发至关重要。
作者
列出所有Java教程。