Collections 类
Collections 类是 Java 集合框架中的一个工具类,位于 java.util 包下。它提供了一系列静态方法,用于对集合(如 List、Set、Map 等)进行各种操作,包括排序、查找、重排、求极值以及其他方法等。
排序
- 自然排序:
sort(List<T> list)- 原理
此方法用于对实现了 Comparable 接口的元素组成的 List 集合进行自然排序。Comparable 接口定义了一个 compareTo 方法,元素通过该方法来确定自身与其他元素的大小关系。排序时,Collections.sort 方法会调用元素的 compareTo 方法进行比较和排序。
- 原理
- 自定义排序:
sort(List<T> list, Comparator<? super T> c)- 原理
当元素没有实现 Comparable 接口,或者需要按照不同于自然顺序的规则进行排序时,可以使用该方法。通过传入一个 Comparator 接口的实现类,Comparator 接口定义了一个 compare 方法,用于比较两个元素的大小。
- 原理
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
// 定义一个实现了 Comparable 接口的类,用于自然排序演示
class Student implements Comparable<Student> {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 重写 compareTo 方法,按照年龄进行自然排序
@Override
public int compareTo(Student other) {
return Integer.compare(this.age, other.age);
}
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + "}";
}
}
// 定义一个普通类,用于自定义排序演示
class Course {
private String courseName;
private double price;
public Course(String courseName, double price) {
this.courseName = courseName;
this.price = price;
}
public String getCourseName() {
return courseName;
}
public double getPrice() {
return price;
}
@Override
public String toString() {
return "Course{courseName='" + courseName + "', price=" + price + "}";
}
}
public class CollectionsSortDemo {
public static void main(String[] args) {
// 自然排序演示
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("Alice", 22));
studentList.add(new Student("Bob", 20));
studentList.add(new Student("Charlie", 25));
System.out.println("自然排序前的学生列表:");
for (Student student : studentList) {
System.out.println(student);
}
// 使用 Collections.sort 进行自然排序
Collections.sort(studentList);
System.out.println("\n自然排序后的学生列表:");
for (Student student : studentList) {
System.out.println(student);
}
// 自定义排序演示
List<Course> courseList = new ArrayList<>();
courseList.add(new Course("Java Programming", 200.0));
courseList.add(new Course("Python Basics", 150.0));
courseList.add(new Course("Data Science", 300.0));
System.out.println("\n自定义排序前的课程列表:");
for (Course course : courseList) {
System.out.println(course);
}
// 自定义比较器,按照课程价格从高到低排序
Comparator<Course> priceComparator = (c1, c2) -> Double.compare(c2.getPrice(), c1.getPrice());
// 使用 Collections.sort 进行自定义排序
Collections.sort(courseList, priceComparator);
System.out.println("\n自定义排序后的课程列表:");
for (Course course : courseList) {
System.out.println(course);
}
}
}
代码解释:
- 自然排序部分:
- 定义了 Student 类并实现了 Comparable 接口,重写了 compareTo 方法,使其按照学生的年龄进行自然排序。
- 创建了一个 Student 对象的列表 studentList,添加了几个学生对象。
- 打印排序前的学生列表,然后使用 Collections.sort(studentList) 对其进行自然排序,最后打印排序后的学生列表。
- 自定义排序部分:
- 定义了 Course 类,该类没有实现 Comparable 接口。
- 创建了一个 Course 对象的列表 courseList,添加了几个课程对象。
- 打印排序前的课程列表,然后创建了一个 Comparator 匿名实现,按照课程价格从高到低进行比较。
- 使用 Collections.sort(courseList, priceComparator) 对课程列表进行自定义排序,最后打印排序后的课程列表。
查找
Collections 类提供了一些用于在集合中进行查找操作的静态方法,这些方法可以帮助我们在 List 等集合中高效地查找元素。下面详细介绍其中常用的查找方法。
- 二分查找:binarySearch
- 方法签名
int binarySearch(List<? extends Comparable<? super T>> list, T key)
int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) - 原理
二分查找(Binary Search)是一种高效的查找算法,要求被查找的列表必须是有序的(按自然顺序或指定的比较器顺序)。该算法通过不断将搜索区间缩小一半,直到找到目标元素或确定目标元素不存在。 - 参数解释
- 第一个重载方法:适用于列表中的元素实现了 Comparable 接口的情况,使用元素的自然顺序进行查找。
- 第二个重载方法:适用于需要自定义比较规则的情况,通过传入 Comparator 来指定元素的比较方式。
- 返回值
如果找到目标元素,返回其在列表中的索引;如果未找到,返回一个负数,该负数是 (-(插入点) - 1),其中插入点是指将元素插入到列表中保持有序的位置。
- 方法签名
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class BinarySearchExample {
public static void main(String[] args) {
// 自然顺序二分查找示例
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(3);
numbers.add(5);
numbers.add(7);
numbers.add(9);
int result1 = Collections.binarySearch(numbers, 5);
System.out.println("查找 5 的结果索引: " + result1);
int result2 = Collections.binarySearch(numbers, 6);
System.out.println("查找 6 的结果索引: " + result2);
// 自定义顺序二分查找示例
List<String> strings = new ArrayList<>();
strings.add("banana");
strings.add("apple");
strings.add("cherry");
// 先排序
Collections.sort(strings, Comparator.reverseOrder());
int result3 = Collections.binarySearch(strings, "apple", Comparator.reverseOrder());
System.out.println("自定义顺序查找 apple 的结果索引: " + result3);
}
}
- 查找最大 / 最小元素:max 和 min
- 方法签名
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)
public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) - 原理
max 方法用于查找集合中的最大元素,min 方法用于查找集合中的最小元素。可以使用元素的自然顺序(元素实现 Comparable 接口),也可以通过传入 Comparator 自定义比较规则。 - 参数解释
- 当使用自然顺序时,要求集合中的元素实现 Comparable 接口。
- 当使用自定义比较规则时,需要传入一个 Comparator 对象。
- 返回值
返回集合中的最大或最小元素。
- 方法签名
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public int getScore() {
return score;
}
@Override
public String toString() {
return "Student{name='" + name + "', score=" + score + "}";
}
}
public class MaxMinExample {
public static void main(String[] args) {
// 自然顺序查找最大/最小元素示例
List<Integer> numbers = new ArrayList<>();
numbers.add(2);
numbers.add(4);
numbers.add(1);
numbers.add(3);
int maxNumber = Collections.max(numbers);
int minNumber = Collections.min(numbers);
System.out.println("最大的数字: " + maxNumber);
System.out.println("最小的数字: " + minNumber);
// 自定义顺序查找最大/最小元素示例
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 80));
students.add(new Student("Bob", 90));
students.add(new Student("Charlie", 70));
Student highestScoreStudent = Collections.max(students, Comparator.comparingInt(Student::getScore));
Student lowestScoreStudent = Collections.min(students, Comparator.comparingInt(Student::getScore));
System.out.println("最高分的学生: " + highestScoreStudent);
System.out.println("最低分的学生: " + lowestScoreStudent);
}
}
- 注意事项
- 二分查找要求有序:使用 binarySearch 方法时,必须确保列表是有序的,否则结果将不可靠。
- 空集合处理:如果传入的集合为空,max 和 min 方法会抛出 NoSuchElementException 异常,在使用时需要进行空集合的判断。
- null 元素处理:集合中不应该包含 null 元素,否则可能会导致 NullPointerException。
打乱元素次序
Collections 类提供了 shuffle 方法用于打乱集合中元素的次序,该方法可以随机重新排列 List 集合里元素的顺序。以下为你详细介绍这个方法。
- 方法签名及原理
Collections 类提供了两种重载形式的 shuffle 方法:public static void shuffle(List<?> list):使用默认的随机源(Random 对象)来打乱列表中元素的顺序。public static void shuffle(List<?> list, Random rnd):使用指定的随机源 rnd 来打乱列表中元素的顺序,这样可以实现可重复的随机打乱效果(如果使用相同的随机种子初始化 Random 对象)。
- 示例代码
以下是使用 shuffle 方法的示例代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class ShuffleExample {
public static void main(String[] args) {
// 创建一个包含整数的列表
List<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
numbers.add(i);
}
System.out.println("打乱前的列表: " + numbers);
// 使用默认随机源打乱列表元素
Collections.shuffle(numbers);
System.out.println("使用默认随机源打乱后的列表: " + numbers);
// 使用指定随机源打乱列表元素
Random random = new Random(123); // 使用固定种子,保证结果可重复
Collections.shuffle(numbers, random);
System.out.println("使用指定随机源打乱后的列表: " + numbers);
}
}
代码解释
- 创建列表:首先创建了一个包含从 1 到 10 的整数的 ArrayList,并打印出打乱前的列表内容。
- 使用默认随机源打乱元素:调用 Collections.shuffle(numbers) 方法,该方法使用默认的 Random 对象来随机打乱列表中元素的顺序,然后打印出打乱后的列表。
- 使用指定随机源打乱元素:创建一个 Random 对象并指定种子值为 123,调用 Collections.shuffle(numbers, random) 方法,使用这个指定的随机源来打乱列表元素。由于使用了固定的种子,每次运行代码时得到的打乱结果是相同的,这在需要可重复测试的场景中很有用。
- 注意事项
- 线程安全问题:Collections.shuffle 方法本身不是线程安全的。如果在多线程环境下对同一个列表进行打乱操作,可能会导致数据不一致或抛出异常。若需要在多线程环境中使用,需要进行额外的同步处理。
- 列表元素变更:shuffle 方法会直接修改传入的列表,而不会创建新的列表。因此,原列表的元素顺序会被改变。
求极值
Collections 类提供了 max 和 min 方法用于在集合中求极值,即找出集合里的最大元素和最小元素。下面从方法签名、使用示例、注意事项等方面详细介绍。
- 方法签名
- 自然顺序求极值
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll):用于在实现了 Comparable 接口的元素集合中,按照元素的自然顺序找出最大元素。public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll):用于在实现了 Comparable 接口的元素集合中,按照元素的自然顺序找出最小元素。
- 自定义顺序求极值
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp):使用指定的 Comparator 来定义元素之间的比较规则,从而找出集合中的最大元素。public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp):使用指定的 Comparator 来定义元素之间的比较规则,从而找出集合中的最小元素。
- 自然顺序求极值
- 自然顺序求极值
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class NaturalOrderExtremumExample {
public static void main(String[] args) {
// 创建一个包含整数的列表
List<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(5);
numbers.add(20);
numbers.add(15);
// 求最大值
Integer maxNumber = Collections.max(numbers);
System.out.println("列表中的最大值: " + maxNumber);
// 求最小值
Integer minNumber = Collections.min(numbers);
System.out.println("列表中的最小值: " + minNumber);
}
}
在上述代码中,Integer 类实现了 Comparable 接口,所以可以直接使用 Collections.max 和 Collections.min 方法按照自然顺序找出列表中的最大和最小元素。
- 自定义顺序求极值
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public int getScore() {
return score;
}
@Override
public String toString() {
return "Student{name='" + name + "', score=" + score + "}";
}
}
public class CustomOrderExtremumExample {
public static void main(String[] args) {
// 创建一个包含学生对象的列表
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 80));
students.add(new Student("Bob", 90));
students.add(new Student("Charlie", 70));
// 自定义比较器,按分数比较
Comparator<Student> scoreComparator = Comparator.comparingInt(Student::getScore);
// 求分数最高的学生
Student highestScoringStudent = Collections.max(students, scoreComparator);
System.out.println("分数最高的学生: " + highestScoringStudent);
// 求分数最低的学生
Student lowestScoringStudent = Collections.min(students, scoreComparator);
System.out.println("分数最低的学生: " + lowestScoringStudent);
}
}
在这个示例中,Student 类没有实现 Comparable 接口,所以我们创建了一个 Comparator 对象 scoreComparator 来定义学生之间的比较规则(按分数比较),然后使用 Collections.max 和 Collections.min 方法根据这个自定义规则找出分数最高和最低的学生。
- 注意事项
- 空集合处理:如果传入的集合为空,max 和 min 方法会抛出 NoSuchElementException 异常。在调用这些方法之前,应该先检查集合是否为空。
- null 元素处理:集合中不应该包含 null 元素,否则在比较过程中可能会抛出 NullPointerException。在使用 max 和 min 方法之前,要确保集合中没有 null 元素。
- 比较规则一致性:使用自定义 Comparator 时,要保证比较规则的一致性和传递性,否则可能会得到意外的结果。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class EmptyCollectionExample {
public static void main(String[] args) {
List<Integer> emptyList = new ArrayList<>();
if (!emptyList.isEmpty()) {
Integer max = Collections.max(emptyList);
System.out.println("最大值: " + max);
} else {
System.out.println("集合为空,无法求最大值。");
}
}
}
其他方法
Collections 类除了前面提到的排序、查找、打乱元素次序、求极值等方法外,还有许多其他常用方法,下面为你详细介绍。
- 反转列表元素顺序:reverse
- 方法签名
public static void reverse(List<?> list) - 功能
该方法用于反转指定 List 集合中元素的顺序,即原本列表开头的元素会变为列表末尾的元素,反之亦然。 - 示例代码
- 方法签名
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ReverseExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
System.out.println("反转前的列表: " + numbers);
Collections.reverse(numbers);
System.out.println("反转后的列表: " + numbers);
}
}
- 交换列表中两个元素的位置:swap
- 方法签名
public static void swap(List<?> list, int i, int j) - 功能
该方法用于交换指定 List 集合中索引为 i 和 j 的两个元素的位置。 - 示例代码
- 方法签名
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SwapExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("cherry");
fruits.add("date");
System.out.println("交换前的列表: " + fruits);
Collections.swap(fruits, 1, 3);
System.out.println("交换后的列表: " + fruits);
}
}
- 填充列表元素:fill
- 方法签名
public static <T> void fill(List<? super T> list, T obj) - 功能
该方法用于将指定 List 集合中的所有元素替换为指定的对象 obj。 - 示例代码
- 方法签名
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class FillExample {
public static void main(String[] args) {
List<String> colors = new ArrayList<>();
colors.add("red");
colors.add("blue");
colors.add("green");
System.out.println("填充前的列表: " + colors);
Collections.fill(colors, "yellow");
System.out.println("填充后的列表: " + colors);
}
}
- 复制列表元素:copy
- 方法签名
public static <T> void copy(List<? super T> dest, List<? extends T> src) - 功能
该方法用于将源列表 src 中的所有元素复制到目标列表 dest 中。目标列表 dest 的长度必须至少等于源列表 src 的长度,否则会抛出 IndexOutOfBoundsException 异常。 - 示例代码
- 方法签名
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CopyExample {
public static void main(String[] args) {
List<Integer> source = new ArrayList<>();
source.add(1);
source.add(2);
source.add(3);
List<Integer> destination = new ArrayList<>();
for (int i = 0; i < source.size(); i++) {
destination.add(0);
}
System.out.println("复制前的目标列表: " + destination);
Collections.copy(destination, source);
System.out.println("复制后的目标列表: " + destination);
}
}
- 检查两个列表是否不相交:disjoint
- 方法签名
public static boolean disjoint(Collection<?> c1, Collection<?> c2) - 功能
该方法用于检查两个集合 c1 和 c2 是否没有共同的元素。如果两个集合没有共同元素,则返回 true;否则返回 false。 - 示例代码
- 方法签名
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DisjointExample {
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
List<Integer> list2 = new ArrayList<>();
list2.add(4);
list2.add(5);
list2.add(6);
List<Integer> list3 = new ArrayList<>();
list3.add(2);
list3.add(7);
list3.add(8);
boolean isDisjoint12 = Collections.disjoint(list1, list2);
boolean isDisjoint13 = Collections.disjoint(list1, list3);
System.out.println("list1 和 list2 是否不相交: " + isDisjoint12);
System.out.println("list1 和 list3 是否不相交: " + isDisjoint13);
}
}

1996

被折叠的 条评论
为什么被折叠?



