您的位置:首页 > 编程语言 > Java开发

【工作笔记】java1.8新特性之stream初使用:list分组、实体转换、求和

2017-12-07 10:34 926 查看
最近在工作中遇到如下情况,需要将页面获取的list数据根据其中一个字段进行分组,数据示意如图:



图中数据为明细,需要根据fid进行分组,将明细归到以fid创建的主单下面,即

fid1--itemA,itemB;

fid2--itemC,itemD......

起初用的是原始的循环方法,代码如下:

/**
* 处理主单及明细
* @param itemList
* @param flag
*/
public void processHqPurchaseOrderAndItems(List<PurchaseOrderItemVo> itemList, String flag){

Map<String, List<PurchaseOrderItems>> map = new HashMap<String, List<PurchaseOrderItems>>();

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<PurchaseOrderItems> list = new ArrayList<PurchaseOrderItems>();
list.add(i);
// 放入map
map.put(v.getFid(), list);
}else{
// map包含这个key
if(map.containsKey(v.getFid())){
// 获取key对应的value,添加明细
List<PurchaseOrderItems> list = map.get(v.getFid());
list.add(i);
// 放入map
map.put(v.getFid(), list);
}else{
// map不包含这个key,创建value,添加明细
List<PurchaseOrderItems> list = new ArrayList<PurchaseOrderItems>();
list.add(i);
// 放入map
map.put(v.getFid(), list);
}
}
}

// 处理map
for (Map.Entry<String, List<PurchaseOrderItems>> entry : map.entrySet()) {
String fid = entry.getKey();
List<PurchaseOrderItems> 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<PurchaseOrderItemVo> itemList, String flag, String reachTime, String remark){
// 处理数据,得到每个fid对应的明细,key--value
Map<String, List<PurchaseOrderItemVo>> countryToLocales = itemList.stream().collect(Collectors.groupingBy(PurchaseOrderItemVo::getFid));
// 处理采购单及明细
for (Map.Entry<String, List<PurchaseOrderItemVo>> entry : countryToLocales.entrySet()) {
String fid = entry.getKey();
// 将vo转换成明细实体
List<PurchaseOrderItems> 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:总感觉还能继续优化,希望哪位朋友能指示下。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  工作 java jdk1.8 stream