ListUtils:你的List专属"手术刀"——精准操作不再大动干戈

89 阅读2分钟

各位List操作专家们好!今天要介绍的是Apache Commons 中的ListUtils工具类。这个工具就像是为List集合量身定制的"瑞士军刀",让你能对List进行精准操作,不再需要为了一个小功能重写整个列表!

一、为什么需要ListUtils?

原生List操作就像:

  • 取两个List的交集?自己写双重循环
  • 分割List?subList边界检查烦死人
  • 不可变空列表?每次都new一个...

而ListUtils就是你的"List操作神器":

// 原始人写法
List<String> emptyList = new ArrayList<>(); // 每次都要new

// 优雅写法
List<String> emptyList = ListUtils.EMPTY_LIST; // 常量空列表

二、ListUtils的"精准手术"

1. 列表运算

// 并集(保留顺序)
List<String> union = ListUtils.union(list1, list2);

// 交集(保留左侧列表顺序)
List<String> intersection = ListUtils.intersection(list1, list2);

// 差集(list1有而list2没有的元素)
List<String> difference = ListUtils.subtract(list1, list2);

// 分区比较(找出差异)
List<String> common = ListUtils.retainAll(list1, list2);
List<String> removed = ListUtils.removeAll(list1, list2);
List<String> added = ListUtils.removeAll(list2, list1);

2. 列表处理

// 固定大小列表(自动截断或填充)
List<String> fixed = ListUtils.fixedSizeList(list);

// 不可变空列表(节省内存)
List<String> empty = ListUtils.EMPTY_LIST;

// 延迟转换列表
List<Integer> transformed = ListUtils.transformedList(
    numbers, 
    n -> n * 2
);

3. 列表分割

// 按大小分块
List<List<String>> chunks = ListUtils.partition(bigList, 100); // 每100个一组

// 获取子列表(自动处理边界)
List<String> safeSubList = ListUtils.subList(list, 10, 20); // fromIndex=10, toIndex=20

三、实战"List微创手术"

1. 数据分页处理

public List<String> getPage(List<String> fullList, int page, int pageSize) {
    int fromIndex = (page - 1) * pageSize;
    int toIndex = Math.min(fromIndex + pageSize, fullList.size());
    return ListUtils.subList(fullList, fromIndex, toIndex);
}

2. 列表差异对比

public ChangeLog compareLists(List<String> oldList, List<String> newList) {
    ChangeLog log = new ChangeLog();
    log.setAddedItems(ListUtils.subtract(newList, oldList));
    log.setRemovedItems(ListUtils.subtract(oldList, newList));
    log.setUnchangedItems(ListUtils.intersection(oldList, newList));
    return log;
}

3. 批量数据处理

public void processInBatches(List<Data> allData) {
    ListUtils.partition(allData, BATCH_SIZE).forEach(batch -> {
        database.batchInsert(batch);
    });
}

四、ListUtils的"手术守则"

  1. 不可变性:EMPTY_LIST等是不可变列表
  2. 视图特性:partition/subList返回的是视图,原列表修改会影响结果
  3. 性能提示:大数据集考虑使用惰性求值的transformedList
  4. 兼容性:与Java集合框架完全兼容

五、与现代Java的"强强联合"

// Java 8 Stream配合使用
ListUtils.partition(bigList, 100).stream()
    .parallel()
    .forEach(this::processBatch);

// Java 16+的toList()简化
List<String> filtered = ListUtils.transformedList(
    rawList, 
    String::trim
).stream()
 .filter(s -> !s.isEmpty())
 .toList();

六、版本特性比较

特性ListUtilsJava Stream APIGuava Lists
易用性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
功能专注度纯List操作通用流操作丰富List扩展
性能中等
学习曲线平缓较陡中等

七、总结

ListUtils就像是:

  • List专用的"手术工具箱"🧰
  • 集合运算的"计算器"🧮
  • 大数据处理的"分块器"🧱
  • 代码简洁的"瘦身师"💃

记住List操作的黄金法则:"好的List操作应该像外科手术——精准、高效、不留后遗症!"

附赠List操作速查表:

场景推荐方法等效Java 8 Stream
安全空列表EMPTY_LISTList.of() (Java 9+)
列表分块partition()需手动实现
安全子列表subList()stream().skip().limit()
列表运算union()/intersection()需自行实现
延迟转换transformedList()stream().map().toList()
固定大小列表fixedSizeList()Collections.unmodifiableList()