Java Collections工具类指南

发布于:2025-05-01 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、Collections工具类概述

java.util.Collections是Java集合框架中提供的工具类,包含大量静态方法用于操作和返回集合。这些方法主要分为以下几类:

  • 排序操作
  • 查找和替换
  • 同步控制
  • 不可变集合
  • 特殊集合视图
  • 其他实用方法

二、排序操作

1. 自然排序

List<String> list = new ArrayList<>(Arrays.asList("banana", "apple", "pear"));

// 自然排序(升序)
Collections.sort(list);
System.out.println(list); // [apple, banana, pear]

// 逆序排序
Collections.sort(list, Collections.reverseOrder());
System.out.println(list); // [pear, banana, apple]

2. 自定义排序

// 使用Comparator
Collections.sort(list, (s1, s2) -> s1.length() - s2.length());
System.out.println(list); // [pear, apple, banana]

// Java 8+更简洁的写法
Collections.sort(list, Comparator.comparingInt(String::length));

3. 随机排序

Collections.shuffle(list);
System.out.println(list); // 随机顺序,如:[banana, pear, apple]

4. 旋转操作

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

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

// 向左旋转1位
Collections.rotate(numbers, -1);
System.out.println(numbers); // [5, 1, 2, 3, 4]

三、查找和替换操作

1. 二分查找

List<Integer> sortedList = Arrays.asList(1, 3, 5, 7, 9);

// 元素存在
int index = Collections.binarySearch(sortedList, 5);
System.out.println(index); // 2

// 元素不存在
index = Collections.binarySearch(sortedList, 6);
System.out.println(index); // -4 (插入点为3,返回-3-1)

2. 极值查找

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

// 最大值
Integer max = Collections.max(numbers);
System.out.println(max); // 9

// 最小值(自定义比较器)
Integer min = Collections.min(numbers, Comparator.reverseOrder());
System.out.println(min); // 9(因为比较器反转)

3. 频率统计

int frequency = Collections.frequency(numbers, 1);
System.out.println(frequency); // 2

4. 替换操作

List<String> words = new ArrayList<>(Arrays.asList("apple", "banana", "apple"));

// 替换所有匹配元素
Collections.replaceAll(words, "apple", "orange");
System.out.println(words); // [orange, banana, orange]

// 填充元素
Collections.fill(words, "fruit");
System.out.println(words); // [fruit, fruit, fruit]

四、同步控制

1. 同步包装器

// 创建线程安全集合
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
Set<Integer> syncSet = Collections.synchronizedSet(new HashSet<>());

// 使用示例
synchronized (syncList) {  // 需要手动同步迭代操作
    Iterator<String> it = syncList.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
}

2. 注意事项

  • 同步集合的方法都是同步的
  • 迭代操作需要额外同步
  • Java 5+推荐使用java.util.concurrent包中的并发集合

五、不可变集合

1. 空集合

List<String> emptyList = Collections.emptyList();
Set<Integer> emptySet = Collections.emptySet();
Map<String, String> emptyMap = Collections.emptyMap();

// 不可修改
// emptyList.add("item"); // 抛出UnsupportedOperationException

2. 单元素集合

List<String> singletonList = Collections.singletonList("one");
Set<Integer> singletonSet = Collections.singleton(2);
Map<String, Integer> singletonMap = Collections.singletonMap("key", 3);

// 不可修改
// singletonList.add("two"); // 抛出UnsupportedOperationException

3. 不可修改视图

List<String> mutableList = new ArrayList<>(Arrays.asList("a", "b", "c"));
List<String> unmodifiableList = Collections.unmodifiableList(mutableList);

// 通过视图修改会抛出异常
// unmodifiableList.add("d"); // UnsupportedOperationException

// 原始列表修改会影响视图
mutableList.add("d");
System.out.println(unmodifiableList); // [a, b, c, d]

六、特殊集合视图

1. 类型安全视图

List rawList = new ArrayList();
rawList.add("string");
rawList.add(1);

// 创建类型安全视图
List<String> checkedList = Collections.checkedList(rawList, String.class);
// checkedList.add(2); // 抛出ClassCastException

2. 不可修改视图

List<String> immutableView = Collections.unmodifiableList(mutableList);
Set<Integer> immutableSetView = Collections.unmodifiableSet(new HashSet<>(numbers));
Map<String, Integer> immutableMapView = Collections.unmodifiableMap(new HashMap<>());

3. 单例视图

Set<String> singleton = Collections.singleton("unique");
List<Integer> singletonList = Collections.singletonList(42);
Map<String, String> singletonMap = Collections.singletonMap("key", "value");

七、其他实用方法

1. 反转顺序

List<Integer> nums = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Collections.reverse(nums);
System.out.println(nums); // [5, 4, 3, 2, 1]

2. 交换元素

Collections.swap(nums, 0, 4);
System.out.println(nums); // [1, 4, 3, 2, 5]

3. 添加多个元素

Collections.addAll(nums, 6, 7, 8);
System.out.println(nums); // [1, 4, 3, 2, 5, 6, 7, 8]

4. 不相交检查

List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(4, 5, 6);
boolean disjoint = Collections.disjoint(list1, list2);
System.out.println(disjoint); // true

八、Java 8+增强功能

1. 新增方法

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 替换所有元素
names.replaceAll(String::toUpperCase);
System.out.println(names); // [ALICE, BOB, CHARLIE]

// 删除满足条件的元素
names.removeIf(name -> name.length() > 4);
System.out.println(names); // [BOB]

2. 与Stream API结合

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

// 转换为不可修改集合
List<Integer> immutable = Collections.unmodifiableList(
    numbers.stream()
        .filter(n -> n > 2)
        .sorted()
        .collect(Collectors.toList())
);
System.out.println(immutable); // [3, 4, 5, 9]

九、性能考虑与最佳实践

1. 排序性能

  • Collections.sort()使用优化的归并排序算法
  • 平均和最坏时间复杂度均为O(n log n)
  • 对于小列表(元素数<7),使用插入排序

2. 同步集合选择

场景 推荐实现
读多写少 CopyOnWriteArrayList
高并发Map ConcurrentHashMap
阻塞队列 ArrayBlockingQueue/LinkedBlockingQueue
简单同步 Collections.synchronizedXXX

3. 最佳实践

  1. 优先使用不可变集合:保证线程安全
  2. 避免频繁排序:大数据集考虑使用TreeSet/TreeMap
  3. 正确使用同步包装器:迭代操作需要额外同步
  4. 合理选择集合类型:根据访问模式选择实现类

十、实际应用案例

1. 实现多值Map

Map<String, List<String>> multiMap = new HashMap<>();

// 使用computeIfAbsent简化操作
multiMap.computeIfAbsent("fruits", k -> new ArrayList<>()).add("apple");
multiMap.computeIfAbsent("fruits", k -> new ArrayList<>()).add("banana");

// 使用Collections工具类创建空列表
multiMap.putIfAbsent("vegetables", Collections.emptyList());

2. 数据统计分析

List<Integer> scores = Arrays.asList(85, 92, 78, 90, 82, 95, 88);

// 计算统计信息
int max = Collections.max(scores);
int min = Collections.min(scores);
double avg = scores.stream().mapToInt(i -> i).average().orElse(0);

// 获取前3名
List<Integer> top3 = scores.stream()
    .sorted(Collections.reverseOrder())
    .limit(3)
    .collect(Collectors.toList());

3. 安全发布集合

public class DataHolder {
    private final List<String> data;
    
    public DataHolder(Collection<String> input) {
        // 防御性复制+不可变包装
        this.data = Collections.unmodifiableList(new ArrayList<>(input));
    }
    
    public List<String> getData() {
        return data; // 安全发布,外部无法修改
    }
}

十一、常见问题与解决方案

1. UnsupportedOperationException

List<String> fixedSize = Arrays.asList("a", "b", "c");
// fixedSize.add("d"); // 抛出异常

// 解决方案:创建新ArrayList
List<String> mutable = new ArrayList<>(fixedSize);
mutable.add("d");

2. 并发修改异常

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));

// 错误方式
for (String s : list) {
    if (s.equals("b")) {
        list.remove(s); // 可能抛出ConcurrentModificationException
    }
}

// 正确方式1:使用迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if (it.next().equals("b")) {
        it.remove();
    }
}

// 正确方式2:Java 8+ removeIf
list.removeIf(s -> s.equals("b"));

3. 性能陷阱

// 低效方式:频繁排序
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
    numbers.add(random.nextInt());
    Collections.sort(numbers); // 每次添加都排序
}

// 高效方式:批量添加后排序
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
    numbers.add(random.nextInt());
}
Collections.sort(numbers); // 单次排序

十二、总结

Collections工具类提供了丰富的静态方法来操作和返回集合,主要功能包括:

  1. 排序和查找sort(), binarySearch(), reverse()
  2. 同步控制synchronizedXXX()方法创建线程安全集合
  3. 不可变集合emptyXXX(), singletonXXX(), unmodifiableXXX()
  4. 特殊视图checkedXXX()类型安全视图
  5. 实用操作reverse(), shuffle(), swap()

最佳实践建议

  • 优先使用不可变集合保证线程安全
  • 大数据集排序考虑使用parallelSort()
  • 多线程环境选择适当的同步策略
  • Java 8+结合Stream API实现更简洁的操作

通过合理使用Collections工具类,可以大大提高集合操作的效率和代码的可维护性。


网站公告

今日签到

点亮在社区的每一天
去签到