Java集合工具类案例如何使用

wen java案例 24

玩转Java集合工具类:从入门到实战案例全解析

📖 文章导读

  1. Java集合框架概览
  2. 核心工具类Collections与Arrays
  3. 实战案例一:使用Collections对List排序与搜索
  4. 实战案例二:利用Arrays高效处理数组与集合转换
  5. 精选问答:集合工具类常见陷阱与最佳实践
  6. 如何在实际项目中灵活运用

Java集合框架概览

在Java开发中,集合框架(Collection Framework)是处理数据结构的基石,它提供了List、Set、Map等接口及实现类,而java.util.Collectionsjava.util.Arrays则是官方提供的高效工具类,能大幅简化集合操作。

Java集合工具类案例如何使用

为什么要学集合工具类?

  • 避免重复造轮子:排序、查找、同步、不可变集合等操作已封装好。
  • 提升代码可读性:一行代码完成复杂逻辑,例如Collections.reverse(list)
  • 性能优化:工具类方法经过底层优化,比如Arrays.asList()的视图机制。

核心工具类Collections与Arrays

1 Collections工具类

常用方法一览:
| 方法签名 | 功能说明 |
|----------|----------|
| sort(List<T> list) | 自然排序(元素需实现Comparable) |
| sort(List<T> list, Comparator<? super T> c) | 自定义排序 |
| binarySearch(List<? extends Comparable<? super T>> list, T key) | 二分查找(需先排序) |
| reverse(List<?> list) | 反转顺序 |
| shuffle(List<?> list) | 随机打乱 |
| unmodifiableList(List<? extends T> list) | 返回不可变视图 |
| synchronizedList(List<T> list) | 返回线程安全列表 |

2 Arrays工具类

核心方法:

  • asList(T... a):将数组转为List(注意:返回的是固定大小的视图,不支持增删)
  • sort(int[] a) / sort(T[] a, Comparator):排序数组
  • binarySearch(int[] a, int key):查找元素索引
  • deepToString(Object[] a):多维数组转字符串
  • copyOf(T[] original, int newLength):数组拷贝

实战案例一:使用Collections对List排序与搜索

场景:学生成绩管理系统

需求:有一个学生列表,按成绩降序排列,并快速查找指定成绩的学生。

import java.util.*;
public class StudentManager {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Alice", 85));
        students.add(new Student("Bob", 92));
        students.add(new Student("Charlie", 78));
        // 1. 自定义排序:按成绩降序
        Collections.sort(students, (s1, s2) -> s2.getScore() - s1.getScore());
        System.out.println("排序后:" + students);
        // 2. 二分查找:先排序(自然顺序),再找成绩85的学生
        // 注意:二分查找前必须按相同规则排序
        students.sort(Comparator.comparingInt(Student::getScore));
        int index = Collections.binarySearch(students, new Student("", 85), 
                                                Comparator.comparingInt(Student::getScore));
        System.out.println("成绩85的学生索引:" + (index >=0 ? index : "未找到"));
        // 3. 获取不可变视图
        List<Student> safeList = Collections.unmodifiableList(students);
        // safeList.add(new Student("Test", 100)); // 抛出UnsupportedOperationException
    }
}
class Student {
    private String name;
    private int score;
    // 构造方法、getter、toString...(略)
}

输出:

排序后:[Bob:92, Alice:85, Charlie:78]
成绩85的学生索引:1

关键点:

  • sort() 支持Lambda表达式,比实现Comparator接口更简洁。
  • binarySearch() 必须基于排序后的列表,且比较器一致。
  • unmodifiableList() 返回的是视图,原始列表修改后,视图会同步变化(但无法通过视图修改)。

实战案例二:利用Arrays高效处理数组与集合转换

场景:数据批量处理

需求:将用户输入的ID数组转换为List,快速排序并去重。

import java.util.*;
public class DataProcessor {
    public static void main(String[] args) {
        String[] ids = {"A03", "A01", "A02", "A01", "A04"};
        // 1. 数组转List(注意:不可增删)
        List<String> idList = Arrays.asList(ids);
        // idList.add("A05"); // 报错!因为返回的是固定大小视图
        // 2. 通过TreeSet去重并排序
        Set<String> sortedSet = new TreeSet<>(idList);
        System.out.println("去重排序后:" + sortedSet); // [A01, A02, A03, A04]
        // 3. 复制到可增删的ArrayList
        List<String> editableList = new ArrayList<>(idList);
        editableList.add("A05"); // 正常运行
        // 4. 数组排序(直接修改原数组)
        Arrays.sort(ids);
        System.out.println("原数组已排序:" + Arrays.toString(ids));
        // 5. 快速填充数组
        int[] scores = new int[5];
        Arrays.fill(scores, 100);
        System.out.println("填充后的分数:" + Arrays.toString(scores));
    }
}

常见误区提醒:

  • Arrays.asList() 返回的是Arrays内部类ArrayList(不是java.util.ArrayList),不支持add/remove
  • 若需要可变List,应使用new ArrayList<>(Arrays.asList(arr))
  • Java 9+ 更推荐使用List.of()来创建不可变集合(如List.of("A","B"))。

精选问答:集合工具类常见陷阱与最佳实践

❓ Q1:Collections.sort() 与 List.sort() 有何区别?

答: 两者功能相同,但list.sort(comparator)是List接口的默认方法(Java 8引入),语法更直接。Collections.sort()是静态方法,兼容旧版本,实战中推荐直接调用list.sort()

❓ Q2:如何安全地在多线程环境中使用集合?

答:

  • 使用Collections.synchronizedList(list)包装,但迭代时需手动同步。
  • 更推荐使用java.util.concurrent包下的CopyOnWriteArrayList(读多写少场景)或ConcurrentHashMap
  • 示例:
    List<String> syncList = Collections.synchronizedList(new ArrayList<>());
    synchronized (syncList) {
      Iterator<String> it = syncList.iterator(); // 必须同步
      while(it.hasNext()) { ... }
    }

❓ Q3:查找元素时,for循环与binarySearch哪个更快?

答:

  • 未排序的List:for循环 O(n)。
  • 已排序的List:binarySearch() O(log n),推荐使用。
  • 注意:binarySearch()要求List实现RandomAccess接口(如ArrayList),若为LinkedList则效率低下(需改为for循环或使用索引查找)。

❓ Q4:Arrays.asList()的视图模式有何风险?

答:

  • 通过该List修改元素会同步影响原数组。
  • 不能使用add/remove操作,否则抛出UnsupportedOperationException
  • 最佳实践:若需独立List,立即用new ArrayList<>(Arrays.asList(arr))拷贝。

如何在实际项目中灵活运用

  1. 优先使用工具类而非手写算法:例如排序、查找、反转等场景,一行代码解决。
  2. 注意可变性与线程安全:根据需求选择不可变视图、同步包装或并发集合。
  3. 掌握转换技巧:数组↔集合、不同类型集合互转(如List转Set去重)。
  4. 避免性能陷阱:如LinkedList使用binarySearch或频繁get(index)操作。
  5. 结合Stream API:Java 8+中,集合工具类与Stream结合威力更强(如list.stream().sorted().collect(Collectors.toList()))。

最后一道练习题:
请编写一个方法,接收一个字符串数组,返回一个按字符串长度升序排序且去重后的List。
提示:使用Arrays.asList()TreeSet(或HashSet+Collections.sort())、Comparator.comparingInt(String::length)


文章出处: 本内容为原创综合整理,如需转载请联系作者,感谢阅读!

抱歉,评论功能暂时关闭!