Guava类库——Lists.partition() 高效分批处理列表数据

目录

前言

在日常开发中,我们经常需要将一个大的列表(List)按固定大小切分成多个子列表,用于批量插入数据库、分页请求、限制 API 调用参数数量等场景。手动编写分片逻辑不仅繁琐,还容易出错。

幸运的是,Google Guava 库 提供了一个极其简洁且高效的工具方法:Lists.partition(),一行代码即可完成分批操作。

什么是 Lists.partition()?

Lists.partition() 是 Guava 中 com.google.common.collect.Lists 类提供的静态方法,用于将一个 List 按指定大小分割成多个子列表。

方法签名

public static List<List> partition(List list, int size)

参数说明

参数 说明
list 要被分割的原始列表(不可为 null)
size 每个子列表的最大元素个数(必须 > 0)

返回值

  • 返回 List>:一个"列表的列表"。
  • 每个内层子列表最多包含 size 个元素。
  • 最后一个子列表可能小于 size。
  • 返回的是视图(view),不是深拷贝(但通常只读使用,安全)。

依赖

xml 复制代码
		<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.1-jre</version>
        </dependency>

示例 一

分批处理 List

假设你有 7 个学生对象,需要每批处理 3 个(例如批量插入数据库):

java 复制代码
public class Student {
    String name;

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

    @Override
    public String toString() {
        return name;
    }
}
java 复制代码
import com.google.common.collect.Lists;
import java.util.List;

public class BatchProcessingExample {
    public static void main(String[] args) {

		// 构造学生列表
        List<Student> students = new ArrayList<>();
        students.add(new Student("Alice"));
        students.add(new Student("Bob"));
        students.add(new Student("Charlie"));
        students.add(new Student("David"));
        students.add(new Student("Eve"));
        students.add(new Student("Frank"));
        students.add(new Student("Grace"));


        final int BATCH_SIZE = 3;
        List<List<Student>> batches = Lists.partition(students, BATCH_SIZE);
        for (int i = 0; i < batches.size(); i++) {
            System.out.println("批次 " + (i + 1) + ":"+batches.get(i));
        }
	}
}

输出:

java 复制代码
批次 1:[Alice, Bob, Charlie]
批次 2:[David, Eve, Frank]
批次 3:[Grace]

示例二

将字符串 ID 列表每 4 个分一组,用于 SQL 的 IN 查询(避免超过数据库限制):

java 复制代码
import com.google.common.collect.Lists;
import java.util.List;

public class StringBatchExample {
    public static void main(String[] args) {
        List<String> ids = Arrays.asList("A", "B", "C", "D", "E", "F", "G");

        List<List<String>> partitions = Lists.partition(ids, 4);

        // 模拟分批查询
        partitions.forEach(batch ->
                System.out.println("SELECT * FROM users WHERE id IN (" + String.join(",", batch) + ")")
        );
    }
}

输出结果

java 复制代码
SELECT * FROM users WHERE id IN (A,B,C,D)
SELECT * FROM users WHERE id IN (E,F,G)

适用场景

  • 数据库 IN 查询分批(如 MySQL 单次 IN 建议不超过 1000 项)
  • 批量删除、更新操作
  • 分块处理日志或文件行

注意事项

  1. 时区无关:Lists.partition() 只做结构分割,与数据内容无关。
  2. 不可变性:返回的子列表是原列表的视图,如果原列表被修改,分区结果也会变化(建议对不可变列表使用)。
  3. 空列表处理:若输入元素个数为0的空列表,返回一个包含一个空子列表的列表[],即最外层List的size为0。
  4. 性能高效:内部使用 AbstractList 实现,无额外内存拷贝。

对比:不用 Guava 怎么做?

若不使用 Guava,需手动循环分片:

java 复制代码
List<List<Student>> manualBatches = new ArrayList<>();
for (int i = 0; i < students.size(); i += batchSize) {
    manualBatches.add(students.subList(i, Math.min(i + batchSize, students.size())));
}

总结

Lists.partition(list, size) 是处理分批任务的利器:

一行代码,安全高效地将大列表切分为固定大小的小批次。

无论是 List 、 List 还是其他类型,它都能以泛型方式完美适配。在涉及批量操作的场景中,强烈推荐使用此方法提升代码质量与开发效率。


小贴士: 如果你的项目已使用 Spring、Hutool 或 Apache Commons,它们也提供了类似功能,但 Guava 的 partition 仍是 Java 社区最广泛认可的实现之一。

相关推荐
禹中一只鱼2 小时前
【IDEA 出现 `IDE error occurred`】
java·ide·spring boot·intellij-idea
weixin_408099672 小时前
【保姆级教程】按键精灵调用 OCR 文字识别 API(从0到1完整实战 + 可运行脚本)
java·前端·人工智能·后端·ocr·api·按键精灵
brahmsjiang2 小时前
Java类加载机制解析:从JVM启动到双亲委派,再到Android的特殊实现
android·java·jvm
yaaakaaang2 小时前
十一、享元模式
java·享元模式
卓怡学长2 小时前
基于 SpringBoot 的生活信息分享平台,从 0 到 1 完整实现(附源码 + 数据库)
java·数据库·spring boot·tomcat·maven
ID_180079054732 小时前
Python解析小红书(XHS)笔记评论 API,json数据返回参考
java·服务器·数据库
努力努力再努力wz2 小时前
【C++高阶系列】告别内查找局限:基于磁盘 I/O 视角的 B 树深度剖析与 C++ 泛型实现!(附B树实现源码)
java·linux·开发语言·数据结构·c++·b树·算法
hero.fei2 小时前
RoaringBitmap在SpringBoot中的使用以及与BitSet对比
java·spring boot·spring
Traving Yu2 小时前
Spring源码与框架原理
java·后端·spring