对List进行分组(java8的Stream 分组的groupBy 的使用)
最近在做一个功能:对一个接口接收的List数据进行校验,同一个订单里的一个产品id只能添加一次。本来想是在入库的时候通过SQL语句进行处理的。但是由于这个数据接口之前同事写了很多的校验,是在是又*又长。在度娘上查一下,发现了JAVA8 可以通过Stream对List进行处理(这里主要是关于分组的);
List<Object> newList = objectList.stream().map(Object::getVar).collect(Collectors.toList());
Order order1 = new Order();
order1.setOrderId("123");
Order1.setGoodsId("S1");
Order1.setSales(100);
Order order2 = new Order();
order2.setOrderId("123");
Order2.setGoodsId("S2");
Order1.setSales(200);
Order order2 = new Order();
order2.setOrderId("1234");
Order2.setGoodsId("S3");
Order1.setSales(300);
List<Order> list = new ArrayList();
List.add(order1);
List.add(order2);
List.add(order3);
Map<String,List<Order>> map = list.stream().collect(Collectors.groupingBy(ord -> ord.getOrderId));
//或 Map<String,List<Order>> map = list.stream().collect(Collectors.groupingBy(Order::getOrderId));
如果需要分组前进行判断,可以加个过滤;
Map<String,List<Order>> map = list.stream().filter(ord -> ord.getOrderId!= null)
.collect(Collectors.groupingBy(h -> h.getOrderID));
需要通过两个字段进行分组,groupingBy 里面加了两个字段;
Map<String,List<Order>> map = list.stream().collect(Collectors.groupingBy(ord -> ord.getOrderId+“;”+ ord.getOrderGoodsId()));
分组是按照groupingBy里面拼接的字段进行分组的,我这里加上";"主要是为了区分订单号和产品号;
上面是groupingBy分组器最多见的一个用法,下面简单介绍一下其余用法:
统计每一个分组的count
/**
* 使用java8 stream groupingBy操做,按城市分组list统计count
*/
Map<String,Long> map = list.stream().collect(Collectors.groupingBy(Order::getOrderId, Collectors.counting()));
统计分组平均值
/**
* 使用java8 stream groupingBy操做,按城市分组list并计算分组销售平均值
*/
Map<String,Long> map = list.stream().collect(Collectors.groupingBy(Order::getOrderId, Collectors.averagingInt(Order::getSales)));
统计分组总值
/**
* 使用java8 stream groupingBy操做,按城市分组list并计算分组销售总值
*/
Map<String,Long> map = list.stream().collect(Collectors.groupingBy(Order::getOrderId, Collectors.summingLong(Order::getSales)));
//对Map按照分组销售总值逆序排序
Map<String, Long> finalMap = new LinkedHashMap<>();
map.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue()
.reversed()).forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));