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 社区最广泛认可的实现之一。

相关推荐
Lumos_77715 分钟前
Linux -- 线程
java·jvm·算法
知兀29 分钟前
【MybatisPlus】后端用枚举类,数据库用tinyint,存在枚举类型转换
java
StockTV31 分钟前
印度股票实时数据 NSE和BSE的实时行情、K 线及指数数据
java·开发语言·spring boot·python
User_芊芊君子33 分钟前
【OpenAI 把 AI 玩明白了】:自主推理 + 动态知识图谱,这 4 个技术突破要颠覆行业
java·人工智能·知识图谱
c++之路1 小时前
C++20概述
java·开发语言·c++20
Championship.23.241 小时前
Linux Top 命令族深度解析与实战指南
java·linux·服务器·top·linux调试
橘子海全栈攻城狮1 小时前
【最新源码】养老院系统管理A013
java·spring boot·后端·web安全·微信小程序
逻辑驱动的ken2 小时前
Java高频面试考点18
java·开发语言·数据库·算法·面试·职场和发展·哈希算法
冷雨夜中漫步2 小时前
Claude Code源码分析——Claude Code Agent Loop 详细设计文档
java·开发语言·人工智能·ai
直奔標竿2 小时前
Java开发者AI转型第二十六课!Spring AI 个人知识库实战(五)——联网搜索增强实战
java·开发语言·人工智能·spring boot·后端·spring