JAVA 两个list合并,且按条件排序问题

现在有如下需求

        HashMap<String,Integer> hashMap1=new HashMap<>();
        List<HashMap<String,Integer>> list1=new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            hashMap1.put("A",i);
            hashMap1.put("B",new Random().nextInt(100));
            hashMap1.put("C",new Random().nextInt(100));
            list1.add(hashMap1);
        }
        HashMap<String,Integer> hashMap2=new HashMap<>();
        List<HashMap<String,Integer>> list2=new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            hashMap2.put("B",new Random().nextInt(100));
            hashMap2.put("C",new Random().nextInt(100));
            list2.add(hashMap2);
        }

 

这样一来,list1中的元素顺序,已经按照hashmap的A字段排好顺序,但B和C字段是乱序,同理,hashmap2的B和C字段,也是乱序

那么如何在不打破A字段的排序前提下,将list1和list2合并,并将排序以B字段为主,C字段为辅进行排序?

(可以把A字段看成某个业务的工单序号,B和C字段是日期和时间,合并后的list出现以下效果:

1       20200101      93000(时间和日期可以简单地以数字处理,有序号的为list1中的数据,没有的为list2中的数据)

2       20200101      83001

         20200101      83002

         20200101      84015

3       20200102      153030

         20200102      153100

         20200102      153200

       

 

list添加map代码方法错误、添加的都是同一个map对象,hashMap1=new HashMap<>()应放入for循环中

可以把list1和list2添加到一个list3列表中,然后自定义Comparator排序方法,按照A先排序、没有A字段的排后边、相同条件下再按照B字段排序、之后再按照C排序、最后根据Collections.sort(list3,comparator)方法根据自定义的comparator排序list3

直接自己排序就行了!没必要就是按顺序添加

把list2按照B字段排序,然后遍历list1,依次取出元素并放进新的list3,同时嵌套遍历list2,用list2的B元素Value和list1正在遍历的B元素做比较,大于等于list1当前B元素并小于下一个B元素时候存进list3,最后生成的list3是不是就是你要的list

你这个需求有问题,因为如果不能改变 A 顺序的话,就会出现 B 或 C 不是升序排列的。除非你的数据都是特殊的数据,不会出现这种情况,反正通过随机生成的 B 或者 C,就无法满足需求。

public static void main(String[] args) throws Exception {

    List<HashMap<String,Integer>> list1=new ArrayList<>();
    for (int i = 0; i < 10; i++) {
      HashMap<String,Integer> hashMap1=new HashMap<>();
      hashMap1.put("A",i);
      hashMap1.put("B",new Random().nextInt(100));
      hashMap1.put("C",new Random().nextInt(100));
      list1.add(hashMap1);
    }

    List<HashMap<String,Integer>> list2=new ArrayList<>();
    for (int i = 0; i < 5; i++) {
      HashMap<String,Integer> hashMap2=new HashMap<>();
      hashMap2.put("B",new Random().nextInt(100));
      hashMap2.put("C",new Random().nextInt(100));
      list2.add(hashMap2);
    }

    // 先将两个列表进行合并
    list1.addAll(list2);

    // 再按照规则进行排序
    list1.sort((m1, m2) -> {
      // 1. 如果 m1 和 m2 都有 A 的话,那么就按照 A 的值升序排列
      if (m1.containsKey("A") && m2.containsKey("A")) {
        return m1.get("A") - m2.get("A");
      }
      // 2. 如果 m1 和 m2 有一个没有 A,则以 B 进行排序
      Integer m1B = m1.get("B");
      Integer m2B = m2.get("B");
      if (!m1B.equals(m2B)) {
        return m1B - m2B;
      } else {
        return m1.get("C") - m2.get("C");
      }
    });

    for (HashMap<String, Integer> map : list1) {
      String a = map.containsKey("A") ? map.get("A").toString() : " ";
      System.out.println( a + "   " + map.get("B") + "   " + map.get("C"));
    }
  }

结果就可能会像这样:

我的理解是:

1.两个map都有A时,先比A再比B最后比C;

2.两个map都没有A时,先比B再比C;

3.两个map只有一个有A时,记有A的为mapA,没有A的为map,则

(1)mapA的B比map的B大,map优先;

(2)mapA的B比map的B小,mapA优先;

(3)mapA的B与map的B相等,mapA优先;

public static void main(String[] args) {
        List<HashMap<String, Integer>> list1 = new ArrayList<>();
        list1.add(createHashMap(1, 20200101, 93000));
        list1.add(createHashMap(2, 20200101, 83001));
        list1.add(createHashMap(3, 20200102, 153030));
        List<HashMap<String, Integer>> list2 = new ArrayList<>();
        list2.add(createHashMap(null, 20200101, 83002));
        list2.add(createHashMap(null, 20200101, 84015));
        list2.add(createHashMap(null, 20200102, 153100));
        list2.add(createHashMap(null, 20200102, 153200));
        List<HashMap<String, Integer>> allList = new ArrayList<>();
        allList.addAll(list1);
        allList.addAll(list2);
        Collections.sort(allList, comparator);
        System.out.println();
        allList.forEach(data -> {
            String valueA = data.containsKey("A") ? data.get("A").toString() : " ";
            System.out.println(valueA + "   " + data.get("B") + "   " + data.get("C"));
        });
    }

    public static HashMap<String, Integer> createHashMap(Integer a, int b, int c) {
        HashMap<String, Integer> hashMap = new HashMap<>();
        if (a != null) {
            hashMap.put("A", a);
        }
        hashMap.put("B", b);
        hashMap.put("C", c);
        return hashMap;
    }

    public static Comparator<HashMap<String, Integer>> comparator = (a, b) -> {
        int Bcompare = a.get("B").compareTo(b.get("B"));
        if (a.containsKey("A") && b.containsKey("A")) {
            int Acompare = a.get("A").compareTo(b.get("A"));
            return Acompare == 0 ? (Bcompare == 0 ? a.get("C").compareTo(b.get("C")) : Bcompare) : Acompare;
        } else if (a.containsKey("A") && !b.containsKey("A")) {
            return a.get("B") > b.get("B") ? 1 : -1;
        } else if (!a.containsKey("A") && b.containsKey("A")) {
            return a.get("B") < b.get("B") ? -1 : 1;
        } else {
            return Bcompare == 0 ? a.get("C").compareTo(b.get("C")) : Bcompare;
        }
    };

按照楼主给出的数据,输出结果为:

将3       20200102      153030改为0       20200102      153030,输出结果为: