JAVA 17中List按照组合键分组

打印 上一主题 下一主题

主题 1003|帖子 1003|积分 3011

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
概述


之前给公司的供应链同事开发了一个通过管理背景下单的功能,他们会把订单数据放到excel里,然后导入到管理背景,就能给门店下单了。
但是当时上线时,没有做校验excel里是否有重复记录的功能,导致一不小心,就会重复下单。
使用JAVA的分组功能校验重复数据


由于给门店下单的数量不多,一样平常不会超过500单,因此不需要分批处置处罚,就直接一次性处置处罚即可。
那么怎样算是重复的订单?
   门店 + 物料 + 到货日期
  只要这三个字段是一样的记录,就认为是重复的,必须提醒操作人,excel有重复记录。
在JAVA的List里,如果想对List里的对象的【多个字段】进行分组,可以采取Function来自定义一个组合键:
  1. Function<Order, String> compositeKey = order -> String.format("%s_%s",
  2.         order.getShopName(),order.getMaterialName(),order.getArrivalDay());
复制代码
定义好这个组合键后,就可以传入到Collectors.groupingBy()方法里,让List按照组合键进行分组。
  1.         Map<String, Long> groupByOrderKeyMap = orderList.stream().collect(Collectors.groupingBy(compositeKey,Collectors.counting()));
复制代码
一旦有重复的记录,就抛出非常,提示操作人记录重复了。
  1.   groupByOrderKeyMap.entrySet().stream()
  2.                 .filter(entry -> entry.getValue() > 1)
  3.                 .findFirst()
  4.                 .ifPresent(entry -> {
  5.                     String [] keyArray = entry.getKey().split("_");
  6.                     String msg = "表格里有重复记录:"+keyArray[0]+","+keyArray[1];
  7.                     throw new RuntimeException(msg);
  8.                 });
复制代码
更优雅的方式


上面的代码里,是使用String.format()方法,将对象的多个字段拼接起来,作为组合key的,这样在解析组合key的时候,就需要使用split()方法进行切割,不太优雅。
其实可以在Order对象里创建一个构造方法,传入门店、物料以及到货日期,然后把整个对象作为组合key的。
  1. @Data
  2. public class Order {
  3.     private String arrivalDay;
  4.     private String materialName;
  5.     private String shopName;
  6.     public Order(String shopName, String materialName, String arrivalDay) {
  7.         this.arrivalDay = arrivalDay;
  8.         this.materialName = materialName;
  9.         this.shopName = shopName;
  10.     }
  11.    @Override
  12.     public boolean equals(Object o) {
  13.         if (this == o) return true;
  14.         if (o == null || getClass() != o.getClass()) return false;
  15.         Order order = (Order) o;
  16.         return Objects.equals(arrivalDay, order.arrivalDay) &&
  17.                Objects.equals(materialName, order.materialName) &&
  18.                Objects.equals(shopName, order.shopName);
  19.     }
  20.     @Override
  21.     public int hashCode() {
  22.         return Objects.hash(arrivalDay, materialName, shopName);
  23.     }
  24. }
复制代码
重写equals和hashCode方法后,就可以使用如下代码进行分组了。
  1. Map<Order, Long> groupByOrderKeyMap = orders.stream()
  2.             .collect(Collectors.groupingBy(o -> new Order(o.getShopName(), o.getMaterialName(), o.getArrivalDay()),Collectors.counting()));
复制代码
这样获取组合key的时候,拿到就是一个Order对象,可以非常方便的获取到对象的字段值。
  1.   groupByOrderKeyMap.entrySet().stream()
  2.                 .filter(entry -> entry.getValue() > 1)
  3.                 .findFirst()
  4.                 .ifPresent(entry -> {
  5.                     String msg = "表格里有重复记录:"+entry.getShopName()+","+entry.getMaterialName();
  6.                     throw new RuntimeException(msg);
  7.                 });
复制代码
如果想把全部重复的记录都找出来,怎么做?


上面的代码是,只要有一条记录出现重复了,就立刻抛出非常。操作人处置处罚完后,大概还有重复记录他不知道,就又得处置处罚一次甚至多次。
最好能一次性告知操作人,excel里有哪些记录重复了,这样操作人就可以一次性处置处罚掉。代码如下:
  1. Function<Order, String> compositeKey = order -> String.format("%s_%s",
  2.         order.getShopName(),order.getMaterialName(),order.getArrivalDay());
  3.         Map<String, List<Order> groupByOrderKeyMap = orderList.stream().collect(Collectors.groupingBy(compositeKey,Collectors.toList()));
复制代码
输出全部重复的记录
  1. groupByOrderKeyMap.values().stream()  
  2.                 .filter(list -> list.size() > 1)  
  3.                 .forEach(duplicates -> {  
  4.                     duplicates.forEach(order -> System.out.println(order));  
  5.                 });  
  6.       
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南七星之家

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表