编程中细节失误记录

2020-12-12  本文已影响0人  楼兰King
开发中遇到填坑

   List<ExcelTemplate> excelTemplatesList = new ArrayList<>();
    Map<String,List<ExcelTemplate>> mpList=excelTemplatesList.stream().collect(Collectors.groupingBy(ExcelTemplate::getBusinseeType));
    for(Map.Entry<String,List<ExcelTemplate>> mp:mpList.entrySet()){
            List<ExcelTemplate> templates=mp.getValue();
            List<String> disList= ToolUtils.getDuplicateValue(templates,lst->lst.getColumnExcelName());
    }
    /**校验集合对象,筛选出重复值
   * */
  public static <E, R> List<R> getDuplicateValue(List<E> list, Function<E, R> function) {

      Map<R, Long> frequencies = list.stream().collect(Collectors.groupingBy(function, Collectors.counting()));
      return frequencies.entrySet().stream()
              .filter(entry -> entry.getValue() > 1).map(entry -> entry.getKey()).collect(Collectors.toList());

  }
  上面方法经过改造如下:
  public static int matchStrValue(List<ExcelTemplate> list) {

        Map<String, Long> frequencies = list.stream().collect(Collectors.groupingBy(lst->lst.getColumnExcelName(), Collectors.counting()));
        List<String> list1=new ArrayList<>();
        //key中有多个字段逗号字符串格式,需要校验key中是否有重复,同一个数据类型中,数据中心字段对应文件字段,允许一对多,但不允许一个文件字段对应多个数据中心字段
        for(Map.Entry<String,Long> mp:frequencies.entrySet()){
           list1.add(mp.getKey());
        }
        long count = list1.stream().distinct().count();
        return  new Long(count).intValue();
    }
    其实list打印出来是
[供应商名称, 单价, 有效期,型号1, 采购表主键, 生产厂家,厂家1,厂家2, 单位, 产品批号, 采购行为, 数量, 通用名, 子公司名称, 日期, 供应商代码, 产品型号,型号1,型号2, 产品规格, 经销商名称, 采购备注, 原厂发货清单, 经销商代码, 采购单号, 仓库, 进货单号, 产品代码, 生产日期, 订单日期, 产品名称, 物权, 产品线, 金额]
    但是去重校验却不生效,问题出在map解析上
    因为原始的map结构如下,key有一个字符串,也有多个字符串逗号分隔的
    {供应商名称=1, 单价=1, 有效期,型号1=1, 采购表主键=1, 生产厂家,厂家1,厂家2=1, 单位=1, 产品批号=1, 采购行为=1, 数量=1, 通用名=1, 子公司名称=1, 日期=1, 供应商代码=1, 产品型号,型号1,型号2=1, 产品规格=1, 经销商名称=1, 采购备注=1, 原厂发货清单=1, 经销商代码=1, 采购单号=1, 仓库=1, 进货单号=1, 产品代码=1, 生产日期=1, 订单日期=1, 产品名称=1, 物权=1, 产品线=1, 金额=1}
    但是其实当赋值的时候,mp.getkey(),添加到list<string>中,看似是一个个字符串,其实真正的隐藏的数据结构还是以每一个mp.getkey()获取的string串的,也就是说这时候去重比较,比如看着型号1,型号1,有两个,其实真正原始数据结构为:
    有效期,型号1
    产品型号,型号1,型号2
    这两个其实是两个独立的一组string字符串,所以去重比较会把它当做
    (有效期,型号1),(产品型号,型号1,型号2)这样去比较,所以造成根本不重复,所以要一个个拆分成独立的string串才可以,最终修改如下即可:
    public static int matchStrValue(List<ExcelTemplate> list) {

        Map<String, Long> frequencies = list.stream().collect(Collectors.groupingBy(lst->lst.getColumnExcelName(), Collectors.counting()));
        List<String> list1=new ArrayList<>();
        //key中有多个字段逗号字符串格式,需要校验key中是否有重复,同一个数据类型中,数据中心字段对应文件字段,允许一对多,但不允许一个文件字段对应多个数据中心字段
        for(Map.Entry<String,Long> mp:frequencies.entrySet()){
            if(mp.getKey().contains(",")){
                String[] split = mp.getKey().split(",");
                for(int i=0;i<split.length;i++){
                    list1.add(split[i]);
                }
            }else {
                list1.add(mp.getKey().toString());
            }
        }
        long count = list1.stream().distinct().count();
        return  new Long(count).intValue();
        调用方法:
        List<ExcelTemplate> excelTemplatesList = new ArrayList<>();
        Map<String,List<ExcelTemplate>> excelNum = excelTemplatesList.stream().collect(Collectors.groupingBy(e ->e.getDataType()));
        校验同一个数据类型中,字段对应是否重复
         for(Map.Entry<String,List<ExcelTemplate>> mp:excelNum.entrySet()){
            String kk=mp.getKey();
            int numCount=ToolUtils.matchStrValue(mp.getValue());
            if(numCount!=mp.getValue().size()){
                throw new BusinessException(new ErrorInfo("field_distinct","文件字段名称不能重复"));
            }
        }
        如上:再次失误,会导致判断误差,因为拿mp的长度去跟去重后比,肯定不对,细节失误。如数据如下:
        mp的原值:
        {供应商名称=1, 单价=1, 有效期,型号1=1, 采购表主键=1, 生产厂家,厂家1,厂家2=1, 单位=1, 产品批号=1, 采购行为=1, 数量=1, 通用名=1, 子公司名称=1, 日期=1, 供应商代码=1, 产品型号,型号1,型号2=1, 产品规格=1, 经销商名称=1, 采购备注=1, 原厂发货清单=1, 经销商代码=1, 采购单号=1, 仓库=1, 进货单号=1, 产品代码=1, 生产日期=1, 订单日期=1, 产品名称=1, 物权=1, 产品线=1, 金额=1}
        由此可以看出,map长度其实是没有拆分前的长度,比如,有效期,型号1这一组多个字符串,而list计算去重,是将mp的key多个值一个个拆分后,然后在去重,长度肯定不一样,所以修改如下:
         public static Map<Integer,Integer> matchStrValue(List<ExcelTemplate> list) {
        Map<String, Long> frequencies = list.stream().collect(Collectors.groupingBy(lst->lst.getColumnExcelName(), Collectors.counting()));
        List<String> list1=new ArrayList<>();
        Map<Integer,Integer> countMap=new HashMap<>();
        for(Map.Entry<String,Long> mp:frequencies.entrySet()){
            if(mp.getKey().contains(",")){
                String[] split = mp.getKey().split(",");
                for(int i=0;i<split.length;i++){
                    list1.add(split[i]);
                }
            }else {
                list1.add(mp.getKey().toString());
            }
        }
        long count = list1.stream().distinct().count();
        return countMap;
    }
     for(Map.Entry<String,List<ExcelTemplate>> mp:excelNum.entrySet()){
            String kk=mp.getKey();
            Map<Integer,Integer> numCount=ToolUtils.matchStrValue(mp.getValue());
            for(Map.Entry<Integer,Integer> num:numCount.entrySet()){
                if(num.getKey()!=num.getValue()){
                    throw new BusinessException(new ErrorInfo("field_distinct","文件字段名称不能重复"));
                }
            }
        }
上一篇 下一篇

猜你喜欢

热点阅读