【工作笔记】java1.8新特性之stream初使用:list分组、实体转换、求和
2017-12-07 10:34
926 查看
最近在工作中遇到如下情况,需要将页面获取的list数据根据其中一个字段进行分组,数据示意如图:
图中数据为明细,需要根据fid进行分组,将明细归到以fid创建的主单下面,即
fid1--itemA,itemB;
fid2--itemC,itemD......
起初用的是原始的循环方法,代码如下:
明显这种写法耗时耗力,第一步要对初始list数据进行for循环根据fid进行分组,得到以fid为key值,对应明细的list为value值的map,再for循环处理map中每一组数据,每次遍历里还要再循环下属list中的amount。
用stream对此业务进行修改,代码如下:
分组、转换、求和,这些操作都只要一行代码就可以完成,大大节省了时间,性能上也更快更好。
ps:总感觉还能继续优化,希望哪位朋友能指示下。
图中数据为明细,需要根据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:总感觉还能继续优化,希望哪位朋友能指示下。
相关文章推荐
- 学习笔记5:java 1.8 Predicate,Function,Supplier,Consumer,Comparator,Optional,Stream接口的使用
- 【笔记】java8中List分组方法的使用
- 使用xStream对(Java对象、List集合、Map )到JSON转换、从JSON转换java对象
- Java基础知识强化之IO流笔记32:转换流之OutputStreamWriter的使用
- Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案
- Java数组转换List后使用用add,remove抛UnsupportedOperationException异常
- 黑马程序员——Java基础——IO流笔记(PrintStream使用示例)
- java笔记之字符串,字符串数组,List<String>的相互转换
- Java-Stream转换List
- java中json包的使用以及字符串,map,list,自定义对象之间的相互转换
- JAVA8的新特性学习笔记-(lambda、stream)
- java中json包的使用以及字符串,map,list,自定义对象之间的相互转换
- [Java]JAVA获取实体与List 数组的转换
- Java工作笔记:部署Tomcat时使用jni和jna调用DLL文件的问题
- 第59课:使用Java和Scala在IDE中实战RDD和DataFrame转换操作’学习笔记
- java工作笔记一 Maven,Guice , Mena的简单使用 ,Eclipse必会快捷键
- hibernate使用本地sql语句查询,解决List<Object[]>转换成List<实体>
- 使用java8新特性 使用stream获取最大值比parallelStream快
- 第60课:使用Java和Scala在IDE中实战RDD和DataFrame动态转换操作学习笔记
- Java List分组及Map使用