最近在工作中遇到如下情况,需要将页面获取的list数据根据其中一个字段进行分组,数据示意如图:
图中数据为明细,需要根据fid进行分组,将明细归到以fid创建的主单下面,即
fid1--itemA,itemB;
fid2--itemC,itemD......
起初用的是原始的循环方法,代码如下:
/**
* 处理主单及明细
* @param itemList
* @param flag
*/
public void processHqPurchaseOrderAndItems(List itemList, String flag){
Map> map = new HashMap>();
for(PurchaseOrderItemVo v : itemList){
PurchaseOrderItems i = new PurchaseOrderItems();
i.setProductId(v.getProductId());
i.setAmount(v.getAmount());
i.setUnit(v.getUnitName());
i.setQty(v.getQty());
// 第一次循环,map为空
if(map.isEmpty() || map.size() < 1){
// 创建value,放入明细i
List list = new ArrayList();
list.add(i);
// 放入map
map.put(v.getFid(), list);
}else{
// map包含这个key
if(map.containsKey(v.getFid())){
// 获取key对应的value,添加明细
List list = map.get(v.getFid());
list.add(i);
// 放入map
map.put(v.getFid(), list);
}else{
// map不包含这个key,创建value,添加明细
List list = new ArrayList();
list.add(i);
// 放入map
map.put(v.getFid(), list);
}
}
}
// 处理map
for (Map.Entry> entry : map.entrySet()) {
String fid = entry.getKey();
List list = entry.getValue();
Integer totalAmount = 0;
for(PurchaseOrderItems i : list){
totalAmount += i.getAmount();
}
// 保存采购单
String orderId = savePurchaseOrder(fid, flag, totalAmount);
// 保存明细
saveItems(list, orderId);
}
}
明显这种写法耗时耗力,第一步要对初始list数据进行for循环根据fid进行分组,得到以fid为key值,对应明细的list为value值的map,再for循环处理map中每一组数据,每次遍历里还要再循环下属list中的amount。
用stream对此业务进行修改,代码如下:
/**
* 处理主单及明细
* @param itemList
* @param flag
*/
public void processHqPurchaseOrderAndItems(List itemList, String flag, String reachTime, String remark){
// 处理数据,得到每个fid对应的明细,key--value
Map> countryToLocales = itemList.stream().collect(Collectors.groupingBy(PurchaseOrderItemVo::getFid));
// 处理采购单及明细
for (Map.Entry> entry : countryToLocales.entrySet()) {
String fid = entry.getKey();
// 将vo转换成明细实体
List list = entry.getValue().stream().map(v->new PurchaseOrderItems(v.getProductId(),
v.getAmount(), "1", v.getUnitName(), v.getQty(), v.getMid())).collect(Collectors.toList());
// 获取明细总金额
Integer totalAmount = list.stream().collect(Collectors.summingInt(PurchaseOrderItems::getAmount));
// 保存采购单
String orderId = savePurchaseOrder(fid, flag, totalAmount, reachTime, remark);
// 保存明细
saveItems(list, orderId);
}}
ps:总感觉还能继续优化,希望哪位朋友能指示下。