public void setCCIStr_XYCD(User user, DfmeaItem dfmeaItem) { // 星宇 客诉信息 if (Constant.CLIENT_XYCD.equals(customer)) { String reasonSerial = dfmeaItem.getReasonSerial(); String raserialNum = dfmeaItem.getRaserialNum(); List<ProjectInvalidNet> net = projectInvalidNetService.getProjectInvalidNetBySecondPidSerial(raserialNum); List<String> list = net.stream().map(ProjectInvalidNet::getFirstPidSerial).collect(Collectors.toList()); list.add(reasonSerial); list.add(raserialNum); List<CustomerComplaintInfoVO> infoVOS = selectInfoListByNodeIds(list); if (CollUtil.isNotEmpty(infoVOS)) { StringBuilder cciStr = new StringBuilder(); for (CustomerComplaintInfoVO infoVO : infoVOS) { cciStr.append(dictionaryService.getDictNameByCode(infoVO.getCustomer(), user.getSiteId())) .append("、") .append(infoVO.getProgramName()) .append(";"); } dfmeaItem.setCciStr(cciStr.toString()); } } } 如果方法第二个参数是LIst集合,该怎么优化大批量数据的情况呢?
时间: 2025-07-11 18:46:13 浏览: 13
<think>好的,用户问的是当方法第二个参数是List集合时,如何优化处理大批量数据的情况。我需要先理解现有代码的功能。原方法处理单个DfmeaItem,当第二个参数变为List后,可能会出现性能问题,比如多次数据库查询,循环处理每个元素效率低。
首先,要考虑批量查询代替逐条查询。原来的代码中,对于每个DfmeaItem,会获取ProjectInvalidNet,然后收集firstPidSerial等,再查询CustomerComplaintInfoVO。如果参数是List,逐个处理会导致多次数据库查询,应该一次性收集所有需要的参数,比如raserialNum和reasonSerial,然后批量查询net数据。
然后,处理ProjectInvalidNet时,可能需要根据raserialNum批量获取所有相关的net记录,而不是每个item单独查。这样可以用一个in查询来获取所有相关的数据,减少数据库访问次数。
接下来,收集所有需要的nodeIds,包括firstPidSerial、reasonSerial和raserialNum,可能会有重复,可以用Set去重。然后批量查询CustomerComplaintInfoVO,这样只需要一次查询就能获取所有需要的信息,而不是每个item都查一次。
然后,需要将查询到的CustomerComplaintInfoVO数据建立一个映射,比如以nodeId为key,这样在处理每个DfmeaItem时,可以快速查找对应的VO,而不需要每次都遍历列表。
此外,使用并行流可能提升处理速度,但要注意线程安全和数据库连接等问题。如果数据量特别大,可能需要分批次处理,避免内存溢出。
代码结构方面,先遍历所有dfmeaItems,收集所有raserialNum,批量查询ProjectInvalidNet,然后收集所有nodeIds,批量查询CustomerComplaintInfoVO,并建立映射。最后再遍历dfmeaItems,利用预取的数据构建cciStr。
还需要处理可能的空值情况,比如raserialNum或reasonSerial为空时,避免添加到list中导致错误。此外,使用StringBuilder时,注意最后的分隔符处理,比如替换最后的“;”为空,或者使用Joiner类来处理拼接。
最后,考虑是否要使用缓存,如果某些数据重复率高,可以缓存dictionaryService的查询结果,减少重复调用。同时,如果customer是固定的,可能进一步优化查询条件。
总结优化步骤:批量查询减少数据库交互,建立映射提高查找效率,并行处理加速,分批次处理大数据,处理字符串拼接,缓存常用数据。</think>当方法参数变为`List<DfmeaItem>`时,处理大批量数据可以通过以下方式优化:
```java
public void setCCIStr_XYCD_Batch(User user, List<DfmeaItem> dfmeaItems) {
if (!Constant.CLIENT_XYCD.equals(customer)) return;
// 1. 批量收集所有需要的参数
Set<String> raserialNums = dfmeaItems.stream()
.map(DfmeaItem::getRaserialNum)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
// 2. 批量查询ProjectInvalidNet
Map<String, List<ProjectInvalidNet>> netMap = projectInvalidNetService
.getProjectInvalidNetBySecondPidSerials(new ArrayList<>(raserialNums))
.stream()
.collect(Collectors.groupingBy(ProjectInvalidNet::getSecondPidSerial));
// 3. 收集所有nodeIds
Set<String> allNodeIds = new HashSet<>();
for (DfmeaItem item : dfmeaItems) {
List<ProjectInvalidNet> nets = netMap.getOrDefault(item.getRaserialNum(), Collections.emptyList());
List<String> firstSerials = nets.stream()
.map(ProjectInvalidNet::getFirstPidSerial)
.collect(Collectors.toList());
allNodeIds.addAll(firstSerials);
if (item.getReasonSerial() != null) allNodeIds.add(item.getReasonSerial());
if (item.getRaserialNum() != null) allNodeIds.add(item.getRaserialNum());
}
// 4. 批量查询客户投诉信息
Map<String, CustomerComplaintInfoVO> infoMap = selectInfoListByNodeIds(new ArrayList<>(allNodeIds))
.stream()
.collect(Collectors.toMap(CustomerComplaintInfoVO::getNodeId, Function.identity()));
// 5. 批量处理数据
dfmeaItems.parallelStream().forEach(item -> {
List<ProjectInvalidNet> nets = netMap.getOrDefault(item.getRaserialNum(), Collections.emptyList());
Set<String> nodeIds = nets.stream()
.map(ProjectInvalidNet::getFirstPidSerial)
.collect(Collectors.toSet());
if (item.getReasonSerial() != null) nodeIds.add(item.getReasonSerial());
if (item.getRaserialNum() != null) nodeIds.add(item.getRaserialNum());
List<CustomerComplaintInfoVO> matchedInfos = nodeIds.stream()
.map(infoMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(matchedInfos)) {
String cciStr = matchedInfos.stream()
.map(info -> dictionaryService.getDictNameByCode(info.getCustomer(), user.getSiteId())
+ "、" + info.getProgramName())
.collect(Collectors.joining(";"));
item.setCciStr(cciStr);
}
});
}
```
优化点解释:
1. **批量数据查询**:将多次数据库查询合并为批量查询,减少数据库访问次数
2. **数据预加载**:提前加载所有需要的数据到内存,避免在循环中频繁访问数据库
3. **内存映射**:使用Map结构存储查询结果,将O(n)查找优化为O(1)
4. **并行处理**:使用parallelStream利用多核CPU优势
5. **去重处理**:使用Set结构避免重复数据
6. **字符串优化**:使用Collectors.joining代替StringBuilder,避免字符串拼接性能问题
需要配套的Service方法改造:
```java
// ProjectInvalidNetService新增方法
List<ProjectInvalidNet> getProjectInvalidNetBySecondPidSerials(List<String> secondPidSerials);
// CustomerComplaintInfoMapper新增方法
List<CustomerComplaintInfoVO> selectInfoListByNodeIds(List<String> nodeIds);
```
阅读全文
相关推荐






