import java.util.*;
import java.util.stream.Collectors;
public class BatchDeviceDataDemo {
// 设备数据类
static class DeviceData {
private String deviceId;
private String dataContent;
public DeviceData(String deviceId, String dataContent) {
this.deviceId = deviceId;
this.dataContent = dataContent;
}
public String getDeviceId() {
return deviceId;
}
public String getDataContent() {
return dataContent;
}
}
// 设备类
static class Device {
private String id;
public Device(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
public static void main(String[] args) {
// -------------------- 模拟数据源 --------------------
// 假设这是从数据库/文件分批读取的模拟方法
List<Device> allDevices = generateAllDevices(100_000); // 10W设备
int batchSize = 1000; // 每批处理1000个设备
// -------------------- 分批次处理 --------------------
for (int batchIndex = 0; batchIndex < allDevices.size(); batchIndex += batchSize) {
// 1. 获取当前批次的设备ID列表
List<Device> currentBatchDevices = allDevices.subList(
batchIndex,
Math.min(batchIndex + batchSize, allDevices.size())
);
List<String> deviceIdsInBatch = currentBatchDevices.stream()
.map(Device::getId)
.collect(Collectors.toList());
// 2. 模拟分批从数据库/文件读取数据(关键优化点!)
List<DeviceData> batchData = loadDataForDevices(deviceIdsInBatch);
// 3. 分组处理当前批次数据
Map<String, List<DeviceData>> batchDataMap = batchData.stream()
.collect(Collectors.groupingBy(DeviceData::getDeviceId));
// 4. 处理当前批次设备
processBatch(currentBatchDevices, batchDataMap);
// 5. 手动释放内存(帮助GC)
batchData.clear();
batchDataMap.clear();
}
}
// --------------- 模拟数据生成方法 ---------------
// 实际场景中应替换为真实的数据访问逻辑(如数据库分页查询)
// 生成所有设备(示例简化)
private static List<Device> generateAllDevices(int count) {
List<Device> devices = new ArrayList<>();
for (int i = 0; i < count; i++) {
devices.add(new Device("DEVICE-" + i));
}
return devices;
}
// 模拟按设备ID列表查询数据(实际应为分页SQL查询或文件分段读取)
private static List<DeviceData> loadDataForDevices(List<String> deviceIds) {
List<DeviceData> data = new ArrayList<>();
// 模拟:假设每个设备有5W条数据
for (String deviceId : deviceIds) {
for (int i = 0; i < 50_000; i++) { // 5W条/设备
data.add(new DeviceData(deviceId, "Data-" + deviceId + "-" + i));
}
}
return data;
}
// --------------- 批次处理逻辑 ---------------
private static void processBatch(List<Device> batchDevices, Map<String, List<DeviceData>> batchDataMap) {
for (Device device : batchDevices) {
String deviceId = device.getId();
List<DeviceData> deviceData = batchDataMap.getOrDefault(deviceId, Collections.emptyList());
// 实际业务逻辑(示例:统计/存储/分析)
System.out.printf("处理设备 %s,数据量:%d(示例展示只处理一批中的前10个设备)\n",
deviceId, deviceData.size());
// 控制台示例输出限制(实际不需要)
if (batchDevices.indexOf(device) >= 10) break;
}
}
}