美文网首页
编程中细节失误记录

编程中细节失误记录

作者: 楼兰King | 来源:发表于2020-12-12 16:48 被阅读0次
开发中遇到填坑

   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","文件字段名称不能重复"));
                }
            }
        }

相关文章

  • 编程中细节失误记录

  • 四、依赖倒置(倒转)原则

    依赖倒置原则:抽象不依赖细节,细节应该依赖抽象;说白了就是:针对接口编程,不要对实现编程。举个例子:在生活中我们使...

  • RxJava基础

    主要记录RxJava的知识点,不涉及原理和细节 简介 利用RxJava实现函数响应式编程 RxJava = 被观察...

  • 随笔1

    细节,注意细节。任何细节上的失误,可能对整个事情带来不利的影响。坚持原则,保守底线,平安健康是最大的幸福。

  • 细节决定成败

    细节决定成败说的人很多,而且有一本书就叫《细节决定成败》,工作生活都一样,工作中你的失误和疏忽会给同事或者公司带来...

  • 记录:为了什么?

    记录编程过程中遇到的坑,以防再次遇到可以节省时间快速解决。 记录编程中摸索出来关于软件及语言的小技巧,提高 cod...

  • 打开编程的正确方式

    设计思路 清晰的逻辑结构,便于实现 编程风格 代码层次明确,变量函数等命名规范 编程细节 考虑周全,没有忽略细节 ...

  • 2018-03-20

    运动结束,记录出现了错误,真好呗 失误

  • 0309读书清单《简单的逻辑学》

    001失误的根源 我们很多判断的失误,根源来自注意力不集中,面对类似的场景,忽略应关注的细节,草率作出决定。 00...

  • 设计模式(依赖倒置原则)

    依赖倒置原则:抽象不应该依赖细节,细节应该依赖抽象。 换成人话:面向接口编程,不要对实现编程。 依赖导致原则A:高...

网友评论

      本文标题:编程中细节失误记录

      本文链接:https://www.haomeiwen.com/subject/kofygktx.html