Lists的分批次操作
1 方法解释
Lists.partition 方法,用于将一个列表分割成多个指定大小的子列表
Lists.partition(List list, int size) 方法接受两个参数:
list:要分割的原始列表。
size:每个子列表的大小。
该方法会将原始列表按照指定的大小分割成多个子列表,并返回一个包含这些子列表的新列表。
示例
假设我们有一个包含 10 个元素的列表,我们想将其分割成每个子列表包含 3 个元素
import com.google.common.collect.Lists;
import java.util.List;
public class PartitionExample {
public static void main(String[] args) {
// 创建一个包含 10 个元素的列表
List<Integer> originalList = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 使用 Lists.partition 方法将列表分割成每个子列表包含 3 个元素
List<List<Integer>> partitions = Lists.partition(originalList, 3);
// 遍历分割后的子列表
for (List<Integer> partition : partitions) {
System.out.println(partition);
}
}
}
输出结果:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10]
2 实际业务场景
1 分批调用 CPI 系统的实现原理
借助Lists.partition方法把待处理的数据列表分割成多个规模较小的子列表,接着依次调用 CPI 系统处理这些子列表,最终汇总所有子列表的处理结果。
代码
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
public class CPIService {
// 模拟调用CPI系统的方法,每次最多处理3条数据
public List<Result> callCPI(List<Request> batchRequests) {
System.out.println("调用CPI系统,处理 " + batchRequests.size() + " 条数据");
List<Result> results = new ArrayList<>();
// 模拟处理每条数据
for (Request request : batchRequests) {
Result result = new Result();
result.setRequestId(request.getId());
result.setSuccess(true);
results.add(result);
}
// 模拟网络延迟
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
return results;
}
// 分批调用CPI系统的方法
public List<Result> batchCallCPI(List<Request> allRequests, int batchSize) {
List<Result> allResults = new ArrayList<>();
// 使用Lists.partition方法将大数据列表分割成多个小批次
List<List<Request>> partitions = Lists.partition(allRequests, batchSize);
// 依次处理每个批次
for (List<Request> batch : partitions) {
List<Result> batchResults = callCPI(batch);
allResults.addAll(batchResults);
}
return allResults;
}
// 示例请求类
static class Request {
private String id;
private String data;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
// 示例结果类
static class Result {
private String requestId;
private boolean success;
private String message;
public String getRequestId() {
return requestId;
}
public void setRequestId(String requestId) {
this.requestId = requestId;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
public static void main(String[] args) {
CPIService service = new CPIService();
// 创建包含10个请求的列表
List<Request> allRequests = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
Request request = new Request();
request.setId("REQ-" + i);
request.setData("数据" + i);
allRequests.add(request);
}
// 分批调用CPI系统,每批处理3条数据
List<Result> results = service.batchCallCPI(allRequests, 3);
// 输出结果
System.out.println("处理完成,共获得 " + results.size() + " 条结果");
for (Result result : results) {
System.out.println("请求ID: " + result.getRequestId() + ", 处理结果: " + (result.isSuccess() ? "成功" : "失败"));
}
}
}
2 代码解析
数据分割:
Lists.partition(allRequests, 3)把包含 10 个请求的列表分割成 4 个子列表,每个子列表分别包含 3、3、3、1 个请求。
分批处理:
借助循环依次处理各个子列表,每次处理 3 条数据。
callCPI方法模拟调用 CPI 系统,实际项目中这里会是真实的网络调用。
结果汇总:
把每个批次的处理结果添加到allResults列表中,最终得到完整的处理结果
3 实际使用优化
- 批次大小设定:
要依据 CPI 系统的性能和限制来确定合适的批次大小。
可以通过配置参数或者动态计算来调整批次大小。 - 错误处理:
要添加重试机制,对网络异常等问题进行处理。
可以采用熔断策略,防止系统崩溃。 - 性能优化:
可以使用多线程并发处理不同批次,提升处理速度。
考虑添加异步处理和结果回调机制。 - 日志监控:
记录每个批次的处理情况,方便后续排查问题。
对关键指标进行监控,如处理时间、成功率等。
通过这种分批调用的方式,能够有效避免因数据量过大导致的调用失败,同时还能提升系统的稳定性和处理效率。