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

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

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

图中数据为明细,需要根据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:总感觉还能继续优化,希望哪位朋友能指示下。

 
  

你可能感兴趣的:(后端)