zoukankan      html  css  js  c++  java
  • List中部分数据按map的排序值排序

    场景

    最近项目上遇到一个需求:运营后台设置商品分子分类组合查询条件,前端APP由子分类进入展示商品列表。
    其中有一种查询条件是在后台添加或导入商品,商品可指定展示的排序,排序号可以重复,也可不设置排序。
    商品需满足特定条件才展示,如定位的门店有库存且上架,即可能后台设置了10个商品,但只有5个商品满足展示条件,也可能都不满足条件都不展示。
    满足上架条件通过ES查询DSL来过滤,后台配置的打分规则用于ES排序,后台设置的商品排序在接口里由Java代码来实现。
    前端APP展示满足条件可展示的商品列表,如果设置了排序号按从小到大排序,如果排序号重复按后台列表展示的顺序展示,如果没有设置排序按ES查询里的打分排序。

    如后台设置了如下商品:
    商品1008,无排序
    商品1001,排序1
    商品1002,排序6
    商品1003,排序5
    商品1004,排序3
    商品1005,排序3
    商品1006,排序4
    商品1007,排序2
    商品1009,无排序

    只有商品1002,1003,1004,1005,1007满足展示条件,那么展示的列表应为:
    商品1007,排序2
    商品1004,排序3
    商品1005,排序3
    商品1003,排序5
    商品1002,排序6
    商品1008,无排序
    商品1009,无排序
    注:因商品1004,1005排序值相同都为3,按后台展示的顺序展示,1004排前面;商品1008,1009没有设置排序,排在列表的最后面。

    实际项目中运营后台设置按商品编码的组合条件为json格式,如:{"productCodes":"1001-1,1002,1003-2"},
    通过构建ES查询条件查询ES,在由Java代码里按运营后台的设置来排序,最后通过redis查询商品库存、价格等构建商品列表数据。
    这里我们主要讨论Java的排序,因此忽略ES查询和构建商品数据,将需求描述简化后,用代码模拟如下:

    // 运营后台已添加且满足可展示条件的商品编码列表,注:1008,1009后台添加了商品但为设置排序号
    List<String> productCodes = new ArrayList<>();
    productCodes.add("1008");
    productCodes.add("1002");
    productCodes.add("1003");
    productCodes.add("1004");
    productCodes.add("1005");
    productCodes.add("1007");
    productCodes.add("1009");
    
    // 运营后台设置的商品排序map,key:商品编码,value:排序号
    Map<String, Integer> productSortMap = new LinkedHashMap<>();
    productSortMap.put("1001", 1);
    productSortMap.put("1002", 6);
    productSortMap.put("1003", 5);
    productSortMap.put("1004", 3);
    productSortMap.put("1005", 3);
    productSortMap.put("1006", 4);
    productSortMap.put("1007", 2);
    

    思路

    1. 遍历productCodes列表,如果设置了排序值在列表中去掉,并且构建一个map保存
    2. 通过该map将不满足可展示条件的商品编码在运营后台设置的商品排序map中去掉
    3. 运营后台设置的商品排序map按value排序,加到productCodes列表的最前面

    实现

    // 遍历productCodes列表,将设置了排序值的商品构建一个map保存,并在列表中去掉该商品
    Map<String, Integer> canDisplayProductSortMap = null;
    Iterator<String> iterator = productCodes.iterator();
    while (iterator.hasNext()) {
        String productCode = iterator.next();
    
        // 在运营后台没有设置排序的跳过处理
        if (!productSortMap.containsKey(productCode)) {
            continue;
        }
    
        // 懒汉模式创建map,当都没设置排序时不用创建map
        if (canDisplayProductSortMap == null) {
            canDisplayProductSortMap = new LinkedHashMap<>();
        }
    
        canDisplayProductSortMap.put(productCode, productSortMap.get(productCode));
        // 将设置了排序的商品编码在列表里去掉
        iterator.remove();
    }
    
    if (canDisplayProductSortMap != null) {
        Map<String, Integer> finalCanDisplayProductSortMap = canDisplayProductSortMap;
        // 通过该map将不满足可展示条件的商品编码在运营后台设置的商品排序map中去掉
        productSortMap.entrySet().removeIf(entry -> !finalCanDisplayProductSortMap.containsKey(entry.getKey()));
        // 运营后台设置的商品排序map按value排序,加到productCodes列表的最前面
        productCodes.addAll(0, productSortMap.entrySet().stream().sorted(Map.Entry.comparingByValue()).map(Map.Entry::getKey).collect(Collectors.toList()));
        // 打印最终排序好的商品编码列表,输出为:[1007, 1004, 1005, 1003, 1002, 1008, 1009]
        System.out.println(productCodes);
    } else {
        // 如果可展示的商品在后台都没有设置排序,则无需处理
        System.out.println(productCodes);
    }
    

    总结

    • list可通过list.iterator()遍历支持在遍历中删除数据
    • map可通过map.entrySet().stream().sorted(Map.Entry.comparingByValue())按value值排序

    参考

  • 相关阅读:
    大华解码器二次开发/C#调用C++DLL
    C# 获取网站页面的句柄
    C# 字节数组 字符数组 字符串 Byte[] Char[] String
    C# 结构体数组 C++ DLL
    Django
    Djano
    Django
    数据分析 02 -Pandas
    数据分析-01 Numpy
    02-正则和xpath
  • 原文地址:https://www.cnblogs.com/cdfive2018/p/14803323.html
Copyright © 2011-2022 走看看