第一部分:Collections工具类概述

理解Java Collections工具类的作用和核心方法

学习目标

掌握Collections工具类的常用方法及其应用场景

Collections工具类的作用

  • 提供操作集合的静态方法
  • 包含排序、查找、替换等常用操作
  • 支持创建不可变集合、同步集合
  • 提供集合的算法实现
  • 简化集合操作代码

常用方法分类

  • 排序方法:sort, reverse, shuffle
  • 查找方法:binarySearch, max, min
  • 替换方法:fill, replaceAll
  • 同步方法:synchronizedXXX
  • 不可变集合:unmodifiableXXX

排序方法

  • sort()
  • reverse()
  • shuffle()
  • rotate()

查找方法

  • binarySearch()
  • max()
  • min()
  • frequency()

同步方法

  • synchronizedList()
  • synchronizedSet()
  • synchronizedMap()
  • synchronizedCollection()

不可变集合

  • unmodifiableList()
  • unmodifiableSet()
  • unmodifiableMap()
  • emptyList()

第二部分:集合排序

掌握Java集合排序的各种方法

学习目标

理解自然排序和自定义排序的区别,掌握Comparable和Comparator的使用

1

自然排序(Comparable)

对象实现Comparable接口进行排序

import java.util.*;

class Student implements Comparable<Student> {
	    private String name;
	    private int score;

	    public Student(String name, int score) {
	    this.name = name;
	    this.score = score;
}

	    // 实现Comparable接口的compareTo方法
@Override
	    public int compareTo(Student other) {
	    // 按分数降序排序
	    return Integer.compare(other.score, this.score);
}

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

public class NaturalSortExample {
	    public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 90));
students.add(new Student("Bob", 85));
students.add(new Student("Charlie", 95));

	    // 使用Collections.sort进行自然排序
Collections.sort(students);

	    // 输出排序结果
	    for (Student s : students) {
System.out.println(s);
}
	    // 输出: Charlie:95, Alice:90, Bob:85
}
}

提示:自然排序适用于对象有自然顺序的情况,如数字、字符串等

2

自定义排序(Comparator)

使用Comparator接口实现灵活排序

import java.util.*;

class Student {
	    private String name;
	    private int score;

	    public Student(String name, int score) {
	    this.name = name;
	    this.score = score;
}

	    public String getName() { return name; }
	    public int getScore() { return score; }

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

public class ComparatorSortExample {
	    public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 90));
students.add(new Student("Bob", 85));
students.add(new Student("Charlie", 95));

	    // 使用Comparator按姓名排序
Collections.sort(students, new Comparator<Student>() {
@Override
	    public int compare(Student s1, Student s2) {
	    return s1.getName().compareTo(s2.getName());
}
});

System.out.println("按姓名排序:");
students.forEach(System.out::println);

	    // 使用Lambda表达式按分数升序排序
Collections.sort(students, (s1, s2) -> Integer.compare(s1.getScore(), s2.getScore()));

System.out.println("\n按分数升序排序:");
students.forEach(System.out::println);

	    // 使用Comparator.comparing方法
Collections.sort(students, Comparator.comparing(Student::getScore).reversed());

System.out.println("\n按分数降序排序:");
students.forEach(System.out::println);
}
}

提示:Comparator提供了更灵活的排序方式,支持多种排序规则

常见错误1:未实现Comparable接口

List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 90));
students.add(new Student("Bob", 85));

// 如果Student未实现Comparable接口,会抛出ClassCastException
Collections.sort(students);

解决方案:确保对象实现Comparable接口,或使用Comparator进行排序

第三部分:Collections工具类常用方法

掌握Collections工具类的核心方法

学习目标

熟练使用Collections工具类进行集合操作

shuffle方法

随机打乱集合顺序

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
System.out.println("原始顺序: " + numbers);

Collections.shuffle(numbers);
System.out.println("打乱后: " + numbers);

binarySearch方法

在有序集合中二分查找元素

List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50);
Collections.sort(numbers); // 确保有序

int index = Collections.binarySearch(numbers, 30);
System.out.println("30的位置: " + index); // 输出: 2

int notFound = Collections.binarySearch(numbers, 35);
System.out.println("35的位置: " + notFound); // 输出: -4

reverse方法

反转集合中元素的顺序

List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");

Collections.reverse(names);
System.out.println("反转后: " + names); // [Charlie, Bob, Alice]

rotate方法

旋转集合中的元素

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// 向右旋转2位
Collections.rotate(numbers, 2);
System.out.println("旋转后: " + numbers); // [4, 5, 1, 2, 3]

常见错误2:在无序集合上使用binarySearch

List<Integer> numbers = Arrays.asList(30, 10, 50, 20, 40);

// 在无序集合上使用binarySearch,结果不可预测
int index = Collections.binarySearch(numbers, 30);

解决方案:使用binarySearch前确保集合已排序

第四部分:同步集合与不可变集合

使用Collections工具类创建线程安全集合和不可变集合

学习目标

掌握多线程环境下集合的安全使用方法

1

同步集合

使用Collections创建线程安全的集合

import java.util.*;

public class SynchronizedCollectionExample {
	    public static void main(String[] args) {
	    // 创建非线程安全的ArrayList
List<String> unsafeList = new ArrayList<>();

	    // 创建线程安全的List
List<String> safeList = Collections.synchronizedList(new ArrayList<>());

	    // 多线程操作
Runnable task = () -> {
	    for (int i = 0; i < 1000; i++) {
safeList.add(Thread.currentThread().getName() + "-" + i);
}
};

Thread t1 = new Thread(task);
Thread t2 = new Thread(task);

t1.start();
t2.start();

	    try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("安全列表大小: " + safeList.size()); // 2000
}
}

提示:同步集合通过在每个方法上加锁实现线程安全

2

不可变集合

使用Collections创建不可修改的集合

import java.util.*;

public class UnmodifiableCollectionExample {
	    public static void main(String[] args) {
List<String> original = new ArrayList<>();
original.add("Java");
original.add("Python");

	    // 创建不可修改的List
List<String> unmodifiableList = Collections.unmodifiableList(original);

	    // 可以修改原始列表
original.add("C++");
System.out.println("不可修改列表: " + unmodifiableList); // [Java, Python, C++]

	    // 尝试修改不可修改列表 - 抛出UnsupportedOperationException
	    try {
unmodifiableList.add("JavaScript");
} catch (UnsupportedOperationException e) {
System.out.println("不能修改不可变集合!");
}

	    // 创建空集合
List<String> emptyList = Collections.emptyList();
Set<Integer> emptySet = Collections.emptySet();
Map<String, String> emptyMap = Collections.emptyMap();
}
}

提示:不可变集合适合作为常量或返回值,防止意外修改

常见错误3:修改不可变集合

List<String> unmodifiableList = Collections.unmodifiableList(
Arrays.asList("Java", "Python")
);

// 尝试添加元素会抛出UnsupportedOperationException
unmodifiableList.add("C++");

解决方案:不可变集合创建后不能修改,需要修改时应创建新集合

第五部分:常见错误与最佳实践

避免Collections使用中的常见陷阱

学习目标

识别并解决Collections使用中的常见问题

排序最佳实践

  • 使用Comparator.comparing简化代码
  • 链式调用thenComparing实现多级排序
  • 使用nullsFirst或nullsLast处理null值
  • 对大数据集考虑使用并行排序

性能优化

  • ArrayList比LinkedList更适合排序
  • 避免频繁创建Comparator实例
  • 使用Arrays.sort对数组排序
  • 对已排序集合使用binarySearch

线程安全

  • 多线程环境使用同步集合
  • 或使用Concurrent集合类
  • 迭代同步集合时需要手动同步
  • 不可变集合天然线程安全

常见错误4:在迭代同步集合时未同步

List<String> syncList = Collections.synchronizedList(new ArrayList<>());

// 线程1添加元素
new Thread(() -> {
	for (int i = 0; i < 1000; i++) {
syncList.add("Item" + i);
}
}).start();

// 线程2迭代集合 - 可能抛出ConcurrentModificationException
new Thread(() -> {
	for (String item : syncList) {
System.out.println(item);
}
}).start();

解决方案:迭代同步集合时手动加锁

// 正确方式:手动同步迭代
synchronized (syncList) {
	for (String item : syncList) {
System.out.println(item);
}
}

第六部分:总结与练习

巩固学习成果,通过练习掌握Collections工具类的使用

学习目标

总结Collections工具类要点,通过实践加深理解

关键知识点总结

  • Collections工具类提供集合操作的静态方法
  • 排序可使用自然排序(Comparable)或自定义排序(Comparator)
  • binarySearch要求集合已排序
  • 使用synchronizedXXX方法创建线程安全集合
  • 使用unmodifiableXXX方法创建不可变集合
  • 避免在迭代同步集合时未同步

动手练习

  1. 创建一个Student类,包含姓名和分数属性,实现Comparable接口按分数排序
  2. 使用Comparator实现按姓名排序和按分数排序两种方式
  3. 创建一个包含100个随机数的列表,使用Collections.sort排序并查找指定值
  4. 实现一个线程安全的购物车,支持多线程添加和删除商品
  5. 创建一个不可变的配置信息集合,包含系统参数