Java 两个 List<Map<String,Obj>> 怎么找出不同的数据呢? 求指点!!!

现在需求是: 有两个
List<Map<String,Object>> list1
List<Map<String,Object>> list2

list1 中的数据会很多; 例如: list1 有100条
list2 中的数据肯定不会比list1多; 例如: list2 有10条
这两条没有上下对应的关系 list1数据和list2顺序也不一样。
暂且把这两个list想象成记录的是用户信息的数据吧
其中list1中的100条数据和list2中的10条数据是一样的 这是期望的结果
但是 偶尔会出现list2中的10条中 其中一条对应不上list1中的100条其中的一条(有时候可能有多条对应不上) 比如 list2中的 王五的acctNo 不等于list1中的 王五acctNo 然后把这条数据给找出来!也就是把这个map找出来(有时候可能有多条,多个map可以返回List<Map>) 这就是需求。

需求变了··· 领导说name也可能不一样! 我特么醉了··· 现在的情况就会是 name不一样, acctNo不一样,phone不一样,date不一样, 我的想法是 两个list先比较name 如果不一样那就存一条, acctNo不一样存一条,phone不一样存一条 date不一样存一条 (这些不相等的数据如果有多条那就是List<Map>), 这个也符合需求 最终商量就是这么干, 这种情况怎么写呀??? 求指点!

给出测试数据:

分割线===================================


新的测试数据 更新于 2020-06-25  22:15

List<String> paramName = Arrays.asList("ORDERNO", "OSORDERID", "AMT", "TRANDATE");
        DataSelector.Result result = DataSelector.init(paramName)
                .addMain(list1())
                .addSub(list2())
                .select();
        System.out.println(JSON.toJSONString(result));
public static   List<Map<String,Object>> list1(){
    List<Map<String,Object>> list1=new ArrayList<>();

    Map<String,Object> mapA1=new HashMap();
    mapA1.put("ORDERNO","o20200611001");
    mapA1.put("OSORDERID","os20200611001");
    mapA1.put("AMT","1000");
    mapA1.put("TRANDATE","20200610");

    mapA1.put("TRXSERNO","seq20200611001");
    list1.add(mapA1);

    Map<String,Object> mapA2=new HashMap();
    mapA2.put("ORDERNO","o20200611002");
    mapA2.put("OSORDERID","os20200611002");
    mapA2.put("AMT","2000");
    mapA2.put("TRANDATE","shanxi");

    mapA2.put("PDATE","Thu Jun 11 00:00:00 CST 2020");
    list1.add(mapA2);

    Map<String,Object> mapA3=new HashMap();
    mapA3.put("ORDERNO","o20200611003");
    mapA3.put("OSORDERID","os20200611003");
    mapA3.put("AMT","3000");
    mapA3.put("TRANDATE","20200610");

    mapA3.put("TRXSERNO","seq20200611003");
    list1.add(mapA3);

    Map<String,Object> mapA4=new HashMap();
    mapA4.put("ORDERNO","o20200611001_01");
    mapA4.put("OSORDERID","os20200611001_01");
    mapA4.put("AMT","1200");

    mapA4.put("TRXSERNO","seq20200611001_01");
    list1.add(mapA4);

    Map<String,Object> mapA5=new HashMap();
    mapA5.put("ORDERNO","o20200611001_03");
    mapA5.put("OSORDERID","os20200611001_03");
    mapA5.put("AMT","3100");
    mapA5.put("TRANDATE","20200610");

    mapA5.put("TRXSERNO","seq20200611001_03");
    list1.add(mapA5);
    return  list1;
}

public static List<Map<String,Object>> list2(){
    List<Map<String,Object>> list2=new ArrayList<>();

    Map<String,Object> mapB3=new HashMap();
    mapB3.put("ORDERNO","o20200611001");
    mapB3.put("OSORDERID","os20200611001");
    mapB3.put("AMT","1000");
    mapB3.put("TRANDATE","20200610");

    mapB3.put("ACCOUNT_NO","DCCX000000001");
    list2.add(mapB3);

    Map<String,Object> mapB2=new HashMap();
    mapB2.put("ORDERNO","o20200611002");
    mapB2.put("OSORDERID","os20200611002");
    mapB2.put("AMT","1000");
    mapB2.put("TRANDATE","shanxi");

    mapB2.put("ACCOUNT_NO","DCCX003");
    list2.add(mapB2);
    return  list2;
}
两种方案执行结果如下:
方案1结果:
{
    "diffList":[
    ],
    "sameList":[
        {
            "ORDERNO":"o20200611001",
            "AMT":"1000",
            "ACCOUNT_NO":"DCCX000000001",
            "OSORDERID":"os20200611001",
            "TRANDATE":"20200610"
        },
        {
            "ORDERNO":"o20200611002",
            "AMT":"1000",
            "ACCOUNT_NO":"DCCX003",
            "OSORDERID":"os20200611002",
            "TRANDATE":"shanxi"
        }]
}

方案2执行结果
{
    "diffList":[
    ],
    "sameList":[
        {
            "ORDERNO":"o20200611001",
            "AMT":"1000",
            "ACCOUNT_NO":"DCCX000000001",
            "OSORDERID":"os20200611001",
            "TRANDATE":"20200610"
        },
        {
            "ORDERNO":"o20200611002",
            "AMT":"1000",
            "ACCOUNT_NO":"DCCX003",
            "OSORDERID":"os20200611002",
            "TRANDATE":"shanxi"
        }]
}


我期望的结果为:
{
    "diffList":[
        {
            "data":{
                "ORDERNO":"o20200611002",
                "AMT":"1000",
                "ACCOUNT_NO":"DCCX003",
                "OSORDERID":"os20200611002",
                "TRANDATE":"shanxi"
            },
            "paramNames":[
                 "AMT"
            ]
        }
    ],
    "sameList":[
        {
            "ORDERNO":"o20200611001",
            "AMT":"1000",
            "ACCOUNT_NO":"DCCX000000001",
            "OSORDERID":"os20200611001",
            "TRANDATE":"20200610"
        }
    ]
}
阅读 978
评论
    4 个回答
    • 2.1k

    究极无敌最终版!!!

    方案1版本代码(mapB2在diff中返回两次):

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public class DataSelector {
    
        private List<Map<String, Object>> mainList;
        private List<Map<String, Object>> subList;
        private List<String> paramNames;
    
        public static DataSelector init(List<String> paramNames) {
            DataSelector dataSelector = new DataSelector();
            dataSelector.paramNames = paramNames;
            return dataSelector;
        }
    
        public DataSelector addMain(List<Map<String, Object>> mainList) {
            this.mainList = mainList;
            return this;
        }
    
        public DataSelector addSub(List<Map<String, Object>> subList) {
            this.subList = subList;
            return this;
        }
    
        public Result select() {
    
            Result result = new Result();
    
            SelectCollectorImpl.Result mainResult = this.mainList.stream().collect(new SelectCollectorImpl(this.paramNames));
    
            Set<String> valueSet = mainResult.getValueSet();
            for (Map<String, Object> map : this.subList) {
                SelectCollectorImpl.Result subResult = SelectCollectorImpl.Result.init(map, this.paramNames);
                if (valueSet.contains(subResult.getFirstValue())) {
                    result.addSame(map);
                }else {
                    List<Map<String, Object>> relatedMapList = mainResult.getRelatedMapList();
                    for (Map<String, Object> relatedMap : relatedMapList) {
                        List<String> diffParamNames = this.paramNames.stream().filter(paramName -> !map.get(paramName).equals(relatedMap.get(paramName))).collect(Collectors.toList());
                        if (diffParamNames.size() != this.paramNames.size()) {
                            result.addDiff(map, diffParamNames);
                        }
                    }
                }
            }
            return result;
        }
    
        @Getter
        @Setter(value = AccessLevel.PRIVATE)
        @NoArgsConstructor(access = AccessLevel.PRIVATE)
        @ToString
        static class Result {
            private List<Map<String, Object>> sameList = new ArrayList<>();
            private List<Diff> diffList = new ArrayList<>();
    
            public Result addSame(Map<String, Object> map) {
                this.sameList.add(map);
                return this;
            }
    
            public Result addDiff(Map<String, Object> data, List<String> paramNames) {
                Diff diff = new Diff(data, paramNames);
                this.diffList.add(diff);
                return this;
            }
    
            @Getter
            @Setter(value = AccessLevel.PRIVATE)
            @AllArgsConstructor(access = AccessLevel.PRIVATE)
            @ToString
            static class Diff {
                private Map<String, Object> data;
                private List<String> paramNames;
            }
        }
    }
    @AllArgsConstructor
    public class SelectCollectorImpl implements Collector<Map<String, Object>, SelectCollectorImpl.Result, SelectCollectorImpl.Result> {
    
        private List<String> keys;
    
        @Override
        public Supplier<Result> supplier() {
            return Result::new;
        }
    
        @Override
        public BiConsumer<Result, Map<String, Object>> accumulator() {
            return (result, map) -> result.addValue(map, this.keys);
        }
    
        @Override
        public BinaryOperator<Result> combiner() {
            return Result::merge;
        }
    
        @Override
        public Function<Result, Result> finisher() {
            return Function.identity();
        }
    
        @Override
        public Set<Characteristics> characteristics() {
            return Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
        }
    
        @Getter
        @Setter(value = AccessLevel.PRIVATE)
        static class Result {
            private Set<String> valueSet = new HashSet<>();
            private List<Map<String, Object>> relatedMapList = new ArrayList<>();
    
            public String getFirstValue() {
                return this.valueSet.stream().findFirst().get();
            }
    
            private Result addValue(Map<String, Object> map, List<String> keys) {
                addValue(this, map, keys);
                return this;
            }
    
            public static Result init(Map<String, Object> map, List<String> keys) {
                Result result = new Result();
                addValue(result, map, keys);
                return result;
            }
    
            private static void addValue(Result result, Map<String, Object> map, List<String> keys) {
                List<String> valueList = new ArrayList<>();
                Map<String, Object> matchMap = new HashMap<>();
                for (String key : keys) {
                    Object value = map.get(key);
                    if (value == null) continue;
                    valueList.add(value.toString());
                    matchMap.put(key, value);
                }
    
                String valueStr = valueList.stream().collect(Collectors.joining("-"));
                result.getValueSet().add(valueStr);
    
                result.getRelatedMapList().add(matchMap);
            }
    
            private Result merge(Result result) {
                this.getValueSet().addAll(result.getValueSet());
                this.getRelatedMapList().addAll(result.getRelatedMapList());
                return this;
            }
        }
    }

    方案2版本代码(mapB2返回一次):

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public class DataSelector {
    
        private List<Map<String, Object>> mainList;
        private List<Map<String, Object>> subList;
        private List<String> paramNames;
    
        public static DataSelector init(List<String> paramNames) {
            DataSelector dataSelector = new DataSelector();
            dataSelector.paramNames = paramNames;
            return dataSelector;
        }
    
        public DataSelector addMain(List<Map<String, Object>> mainList) {
            this.mainList = mainList;
            return this;
        }
    
        public DataSelector addSub(List<Map<String, Object>> subList) {
            this.subList = subList;
            return this;
        }
    
        public Result select() {
    
            Result result = new Result();
    
            SelectCollectorImpl.Result mainResult = this.mainList.stream().collect(new SelectCollectorImpl(this.paramNames));
    
            Set<String> valueSet = mainResult.getValueSet();
            Set<String> sameValueSet = new HashSet<>();
            for (Map<String, Object> map : this.subList) {
                SelectCollectorImpl.Result subResult = SelectCollectorImpl.Result.init(map, this.paramNames);
                String value = subResult.getFirstValue();
                if (valueSet.contains(value)) {
                    result.addSame(map);
                    sameValueSet.add(value);
                }else {
                    Map<String, Map<String, Object>> originalMap = mainResult.getOriginalMap();
                    for (Map.Entry<String, Map<String, Object>> entry : originalMap.entrySet()) {
                        if (sameValueSet.contains(entry.getKey())) continue;
                        List<String> diffParamNames = this.paramNames.stream().filter(paramName -> !map.get(paramName).equals(entry.getValue().get(paramName))).collect(Collectors.toList());
                        if (diffParamNames.size() != this.paramNames.size()) {
                            result.addDiff(map, diffParamNames);
                        }
                    }
                }
            }
            return result;
        }
    
        @Getter
        @Setter(value = AccessLevel.PRIVATE)
        @NoArgsConstructor(access = AccessLevel.PRIVATE)
        @ToString
        static class Result {
            private List<Map<String, Object>> sameList = new ArrayList<>();
            private List<Diff> diffList = new ArrayList<>();
    
            public Result addSame(Map<String, Object> map) {
                this.sameList.add(map);
                return this;
            }
    
            public Result addDiff(Map<String, Object> data, List<String> paramNames) {
                Diff diff = new Diff(data, paramNames);
                this.diffList.add(diff);
                return this;
            }
    
            @Getter
            @Setter(value = AccessLevel.PRIVATE)
            @AllArgsConstructor(access = AccessLevel.PRIVATE)
            @ToString
            static class Diff {
                private Map<String, Object> data;
                private List<String> paramNames;
            }
        }
    }
    
    @AllArgsConstructor
    public class SelectCollectorImpl implements Collector<Map<String, Object>, SelectCollectorImpl.Result, SelectCollectorImpl.Result> {
    
        private List<String> keys;
    
        @Override
        public Supplier<Result> supplier() {
            return Result::new;
        }
    
        @Override
        public BiConsumer<Result, Map<String, Object>> accumulator() {
            return (result, map) -> result.addValue(map, this.keys);
        }
    
        @Override
        public BinaryOperator<Result> combiner() {
            return Result::merge;
        }
    
        @Override
        public Function<Result, Result> finisher() {
            return Function.identity();
        }
    
        @Override
        public Set<Characteristics> characteristics() {
            return Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
        }
    
        @Getter
        @Setter(value = AccessLevel.PRIVATE)
        static class Result {
            private Set<String> valueSet = new HashSet<>();
            private Map<String, Map<String, Object>> originalMap = new HashMap<>();
    
            public String getFirstValue() {
                return this.valueSet.stream().findFirst().get();
            }
    
            private Result addValue(Map<String, Object> map, List<String> keys) {
                addValue(this, map, keys);
                return this;
            }
    
            public static Result init(Map<String, Object> map, List<String> keys) {
                Result result = new Result();
                addValue(result, map, keys);
                return result;
            }
    
            private static void addValue(Result result, Map<String, Object> map, List<String> keys) {
                List<String> valueList = new ArrayList<>();
                for (String key : keys) {
                    Object value = map.get(key);
                    if (value == null) continue;
                    valueList.add(value.toString());
                }
    
                String valueStr = valueList.stream().collect(Collectors.joining("-"));
                result.getValueSet().add(valueStr);
    
                result.getOriginalMap().put(valueStr, map);
            }
    
            private Result merge(Result result) {
                this.getValueSet().addAll(result.getValueSet());
                this.getOriginalMap().putAll(result.getOriginalMap());
                return this;
            }
        }
    }

    究极最终版!!

    我怕需求不清,所以还是建议题主试试我的代码

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public class DataSelector {
    
        private List<Map<String, Object>> mainList;
        private List<Map<String, Object>> subList;
        private List<String> paramNames;
    
        public static DataSelector init(List<String> paramNames) {
            DataSelector dataSelector = new DataSelector();
            dataSelector.paramNames = paramNames;
            return dataSelector;
        }
    
        public DataSelector addMain(List<Map<String, Object>> mainList) {
            this.mainList = mainList;
            return this;
        }
    
        public DataSelector addSub(List<Map<String, Object>> subList) {
            this.subList = subList;
            return this;
        }
    
        public Result select() {
    
            Result result = new Result();
    
            SelectCollectorImpl.Result mainResult = this.mainList.stream().collect(new SelectCollectorImpl(this.paramNames));
    
            Set<String> valueSet = mainResult.getValueSet();
            for (Map<String, Object> map : this.subList) {
                SelectCollectorImpl.Result subResult = SelectCollectorImpl.Result.init(map, this.paramNames);
                if (valueSet.contains(subResult.getFirstValue())) {
                    result.addSame(map);
                }else {
                    Map<String, Set<Object>> valueMap = mainResult.getValueMap();
                    List<String> paramNames = valueMap.entrySet().stream().filter(entry -> !entry.getValue().contains(map.get(entry.getKey()))).map(Map.Entry::getKey).collect(Collectors.toList());
                    if (paramNames.size() == this.paramNames.size()) continue;
                    result.addDiff(map, paramNames);
                }
            }
            return result;
        }
    
        @Getter
        @Setter(value = AccessLevel.PRIVATE)
        @NoArgsConstructor(access = AccessLevel.PRIVATE)
        @ToString
        static class Result {
            private List<Map<String, Object>> sameList = new ArrayList<>();
            private List<Diff> diffList = new ArrayList<>();
    
            public Result addSame(Map<String, Object> map) {
                this.sameList.add(map);
                return this;
            }
    
            public Result addDiff(Map<String, Object> data, List<String> paramNames) {
                Diff diff = new Diff(data, paramNames);
                this.diffList.add(diff);
                return this;
            }
    
            @Getter
            @Setter(value = AccessLevel.PRIVATE)
            @AllArgsConstructor(access = AccessLevel.PRIVATE)
            @ToString
            static class Diff {
                private Map<String, Object> data;
                private List<String> paramNames;
            }
        }
    }
    @AllArgsConstructor
    public class SelectCollectorImpl implements Collector<Map<String, Object>, SelectCollectorImpl.Result, SelectCollectorImpl.Result> {
    
        private List<String> keys;
    
        @Override
        public Supplier<Result> supplier() {
            return Result::new;
        }
    
        @Override
        public BiConsumer<Result, Map<String, Object>> accumulator() {
            return (result, map) -> result.addValue(map, this.keys);
        }
    
        @Override
        public BinaryOperator<Result> combiner() {
            return Result::merge;
        }
    
        @Override
        public Function<Result, Result> finisher() {
            return Function.identity();
        }
    
        @Override
        public Set<Characteristics> characteristics() {
            return Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
        }
    
        @Getter
        @Setter(value = AccessLevel.PRIVATE)
        static class Result {
            private Set<String> valueSet = new HashSet<>();
            private Map<String, Set<Object>> valueMap = new HashMap<>();
    
            public String getFirstValue() {
                return this.valueSet.stream().findFirst().get();
            }
    
            private Result addValue(Map<String, Object> map, List<String> keys) {
                addValue(this, map, keys);
                return this;
            }
    
            public static Result init(Map<String, Object> map, List<String> keys) {
                Result result = new Result();
                addValue(result, map, keys);
                return result;
            }
    
            private static void addValue(Result result, Map<String, Object> map, List<String> keys) {
                List<String> valueList = new ArrayList<>();
                for (String key : keys) {
                    Object value = map.get(key);
                    if (value == null) continue;
                    valueList.add(value.toString());
    
                    Set<Object> objectSet = result.getValueMap().get(key);
                    if (objectSet == null) objectSet = new HashSet<>();
                    objectSet.add(value);
                    result.getValueMap().put(key, objectSet);
                }
    
                String valueStr = valueList.stream().collect(Collectors.joining("-"));
                result.getValueSet().add(valueStr);
            }
    
            private Result merge(Result result) {
                this.getValueSet().addAll(result.getValueSet());
    
                for (Map.Entry<String, Set<Object>> entry : result.getValueMap().entrySet()) {
                    String key = entry.getKey();
                    Set<Object> valueSet = this.valueMap.get(key);
                    if (valueSet == null) valueSet = new HashSet<>();
                    valueSet.addAll(entry.getValue());
                    this.valueMap.put(key, valueSet);
                }
                return this;
            }
        }
    }
    

    写的有点冲忙,没有注释哈,不过意思上基本按照你评论里的需求来做的,也许有些地方有些小问题,你可以先把上面这两个类DataSelectorSelectCollectorImpl复制过去,然后这样去调用

    List<String> paramNames = Arrays.asList("name", "acctNo", "phone", "date");
    DataSelector.Result result = DataSelector.init(paramNames)
                                             .addMain(mapList1)
                                             .addSub(mapList2)
                                             .select();
    System.out.println(result);

    这个最终返回的DataSelector.Result里包含了你需要的两个list,共同的和不同的,你可以自己点进去查看类信息。

    然后init方法里会初始化此次处理的所有字段,你就把你需要所有字段放进去,记住是所有的

    addMain里参数加的是你那100条数据,也就是作为依据匹配的list1

    addSub当然加的参数是你那10条数据,也就是list2

    然后执行试试吧,我简单试了你之前给的两个字段的例子,应该是可以的,下面最后打印出来的result结果,为了方便看我给你转成了json格式的

    {  
    "diffList":\[  
            {  
                "data":{  
                    "acctNo":"456798",  
                    "name":"李四"  
                },  
                "paramNames":\[  
                    "acctNo"  
                \]  
            },  
            {  
                "data":{  
                    "acctNo":"111111",  
                    "name":"王五"  
                },  
                "paramNames":\[  
                    "acctNo"  
                \]  
            }  
        \],  
    "sameList":\[  
            {  
                "acctNo":"123456",  
                "name":"张三"  
            }  
        \]  
    }

    仅供参考~


    华丽的分割线


    更新第三种,根据某个字段去过滤,那这里肯定要写出一个方法了,参数也就是三个,两个List,和最后需要过滤的字段filterParam

    那你想过滤什么字段就过滤什么字段呗,这里面有个NAME是全局的
    (private static final String NAME = "name";)

    private static List<Map<String, Object>> filter(List<Map<String, Object>> mapList1, List<Map<String, Object>> mapList2, String filterParam){
            Map<Object, Object> map1 = mapList1.stream()
                                               .collect(Collectors.toMap(map -> map.get(NAME), map -> map.get(filterParam)));
            List<Map<String, Object>> list = mapList2.stream()
                                                     .filter(map -> !map1.get(map.get(NAME)).equals(map.get(filterParam)))
                                                     .collect(Collectors.toList());
            return list;
        }

    华丽的分割线


    第二波更新
    了解了一下需求,若只是把name相同而acctNo不同的找出来

    String NAME = "name";
    String ACCT_NO = "acctNo";
    Map<Object, Object> map1 = mapList1.stream()
                                       .collect(Collectors.toMap(
                                                 map -> map.get(NAME), 
                                                 map -> map.get(ACCT_NO)));
    List<Map<String, Object>> list = mapList2.stream()
                                             .filter(map -> !map1.get(map.get(NAME)).equals(map.get(ACCT_NO)))
                                             .collect(Collectors.toList());
                                              

    可以去验证一下


    华丽的分割线


    我感觉题主你没有把问题说清楚把,因为从你的描述来看,我感觉你两个List<Map>看似分开,但是实际描述中觉得是对应的,也就是两个List中的每一个map按照List的顺序是对应,你说你只想找出

    image.png

    那我可不可以认为你给出的两个List是上下对应的,那我觉得就简单了。。。直接一个循环就出来了

    List<String> result = new ArrayList<>();
    for (int i = 0; i < mapList.size(); i++) {
         Map<String, Object> stringObjectMap1 = mapList.get(i);
         Map<String, Object> stringObjectMap2 = mapList2.get(i);
         if (!stringObjectMap1.get("acctNo").equals(stringObjectMap2.get("acctNo"))) {
              result.add("acctNo");
         }
    
         if (!stringObjectMap1.get("name").equals(stringObjectMap2.get("name"))) {
              result.add("name");
         }
    }        

    最后我是找出了acctNo,但是其实题主你这里有点小问题,还有个李四的acctNo也不一样哈,你仔细看
    image.png

    当然最后我不知道你到底想要返回什么。。。如果你能把问题描述清楚

    1. 什么样的输出
    2. 经过什么样的操作
    3. 获得什么样的结果

    可能回答的人会更多
    你在评论提到你希望用lambda,那你都不明确你希望最终获取什儿样的结果格式,别人怎么用lambda帮你想,比如你说

    王五 和 王五 的 acctNo不同

    那几个中文字到底对应java的什么返回类型嘛,你说清楚点可能更好点吧

      public class Test {
          public static void main(String[] args) {
              String str1 = "[{\"acctNo\": \"123456\", \"name\": \"张三\"},{\"acctNo\": \"456789\", \"name\": \"李四\"},{\"acctNo\": \"000000\", \"name\": \"王五\"},{\"acctNo\": \"010101\", \"name\": \"张三丰\"} , {\"acctNo\": \"020202\", \"name\": \"詹姆斯\"}]";
              String str2 = "[{\"acctNo\": \"123456\", \"name\": \"张三\"},{\"acctNo\": \"456789\", \"name\": \"李四\"},{\"acctNo\": \"111111\", \"name\": \"王五\"}, {\"acctNo\": \"020202\", \"name\": \"詹斯\"}]";
      
              List<Entity> entityList_1 = JSON.parseArray(str1, Entity.class);
              List<Entity> entityList_2 = JSON.parseArray(str2, Entity.class);
      
              List<Entity> newEntity = entityList_2.stream().filter(item -> !entityList_1.contains(item)).collect(Collectors.toList());
      
              newEntity.forEach(item -> {
                  System.out.println(item + "\n" + validField(new ArrayList<>(entityList_1), item));
              });
      
          }
      
          // 验证某个字段不一致
          private static String validField(List<Entity> standardList, Entity entity) {
              // 获取该实体的所有属性
              Field[] fields = entity.getClass().getDeclaredFields();
              // 遍历属性
              for(int fieldIndex = 0; fieldIndex < fields.length; fieldIndex++) {
                  Field field = fields[fieldIndex];
                  // 该属性所对应的实体值是否包含在列表中,如果包含则缩小列表范围,如果不包含则说明当前实体就是不匹配的实体
                  List<Entity> list = recursiveMethod(standardList, field, entity);
      
                  if(list.size() == 0) {
                      return field.getName();
                  }
              }
      
              return null;
          }
      
          private static List<Entity> recursiveMethod(List<Entity> standardList, Field field, Entity entity) {
              return standardList.stream().filter(item -> {
                  try {
                      field.setAccessible(true);
                      String validValue = (String) field.get(item);
                      String value = (String) field.get(entity);
                      return validValue.equals(value);
                  } catch (IllegalAccessException e) {
                      e.printStackTrace();
                  }
                  return false;
              }).collect(Collectors.toList());
          }
      }
      

      上面是第三次更新的测试类


      实体类

      @Data
      public class Entity {
          private String acctNo;
      
          private String name;
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (!(o instanceof Entity)) return false;
              Entity entity = (Entity) o;
              return Objects.equals(acctNo, entity.acctNo) &&
                      Objects.equals(name, entity.name);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(acctNo, name);
          }
      }
      

      测试类

          public static void main(String[] args) {
              String str1 = "[{\"acctNo\": \"123456\", \"name\": \"张三\"},{\"acctNo\": \"456789\", \"name\": \"李四\"},{\"acctNo\": \"000000\", \"name\": \"王五\"},{\"acctNo\": \"010101\", \"name\": \"张三丰\"} , {\"acctNo\": \"020202\", \"name\": \"詹姆斯\"}]";
              String str2 = "[{\"acctNo\": \"123456\", \"name\": \"张三\"},{\"acctNo\": \"456789\", \"name\": \"李四\"},{\"acctNo\": \"111111\", \"name\": \"王五\"}, {\"acctNo\": \"020202\", \"name\": \"詹斯\"}]";
      
              List<Entity> entityList_1 = JSON.parseArray(str1, Entity.class);
              List<Entity> entityList_2 = JSON.parseArray(str2, Entity.class);
      
              List<Entity> newEntity = entityList_2.stream().filter(item -> !entityList_1.contains(item)).collect(Collectors.toList());
              System.out.println(newEntity);
          }

      用实体类封装 更新需求后


              List<Map<String, Object>> newList = mapList.stream()
                      .filter((mapItem) -> !mapList2.stream()
                              .map(item -> item.get("acctNo"))
                              .collect(Collectors.toList())
                              .contains(mapItem.get("acctNo")))
                      .collect(Collectors.toList());

      大致这样?求A相对于B的差集?

      用for循环来做

              re:
              for(Map<String, Object> mapItem : mapList) {
                  for(Map<String, Object> mapC: mapList2) {
                      if(mapItem.get("acctNo").equals(mapC.get("acctNo"))) {
                          continue re;
                      }
                  }
                  newList2.add(mapItem);
              }

      这里用到了label来实现,你也可以通过设一个count来判断一下是不是遍历到了最后一个

        • 62

        为什么要把对象存map里-。-

          • 474
            public static final String SP = ",";
          
          
          
            @Autowired
            private HsLogMapper hsLogMapper;
          
            /**
             * @param <T>    java bean
             * @param target 目标数据
             * @param source 原始数据
             * @return
             * @throws Exception 反射相关异常
             */
            public static <T> String diffJavaBean(T target, T source) {
              if (target instanceof Collection) {
                return diffCollection(target, source);
              }
          
              Class<?> targetClass = target.getClass();
              Class<?> sourceClass = source.getClass();
              if (targetClass.equals(sourceClass)) {
          
                Field[] declaredFields = targetClass.getDeclaredFields();
                StringBuilder sb = new StringBuilder();
                for (Field declaredField : declaredFields) {
                  filedDiffValueResolution(source, target, targetClass, sourceClass, sb, declaredField);
                }
          
                if (sb.length() > 0) {
                  sb.deleteCharAt(sb.length() - 1);
                }
                String s = sb.toString();
                if (s.split(SP).length > 0) {
                  if (s.indexOf(SP) == 0) {
                    sb.deleteCharAt(0);
                    return sb.toString();
                  }
                  return sb.toString();
                } else {
                  return "";
                }
              } else {
                return "";
              }
            }
          
            private static <T> String diffCollection(T target, T source) {
              List<Object> oldV = new ArrayList<>();
              List<Object> newV = new ArrayList<>();
              getCollectionValue(target, newV);
              getCollectionValue(source, oldV);
              StringBuilder sb = new StringBuilder();
          
              newV.removeAll(oldV);
              for (Object o : newV) {
                sb.append("添加");
                sb.append(JSON.toJSONString(o));
                sb.append(",");
              }
          
              return sb.toString();
            }
          
            private static <T> void getCollectionValue(T target, List<Object> oldV) {
              if (target instanceof Collection) {
                if (!((Collection) target).isEmpty()) {
          
                  Iterator iterator = ((Collection) target).iterator();
                  while (iterator.hasNext()) {
                    Object next = iterator.next();
                    oldV.add(next);
                  }
                }
              }
            }
          
            private static <T> void filedDiffValueResolution(
                T target,
                T source,
                Class<?> targetClass,
                Class<?> sourceClass,
                StringBuilder sb,
                Field declaredField) {
          
              String name = declaredField.getName();
              FiledDiffValue annotation = declaredField.getAnnotation(FiledDiffValue.class);
          
              if (annotation != null) {
                try {
          
                  Object newValue = getFieldValue(target, targetClass, name);
                  Object oldValue = getFieldValue(source, sourceClass, name);
                  Class<?> clazz = annotation.clazz();
          
                  valueDiff(sb, annotation, newValue, oldValue, clazz);
                } catch (Exception e) {
                  // 没有 getter 会出现一个一场直接不处理跳过
                  log.error("{}", e);
                }
              }
            }
          
            /**
             * 值比较差异
             */
            private static void valueDiff(
                StringBuilder sb,
                FiledDiffValue annotation,
                Object newValue,
                Object oldValue,
                Class<?> clazz) {
              String ov = null;
              String nv = null;
              if (oldValue != null && newValue != null) {
          
                if (!oldValue.equals(newValue)) {
          
                  if (clazz.equals(Object.class)) {
          
                    StringBuilder stringBuilder =
                        changeCn(annotation.cnName(), oldValue.toString(), newValue.toString());
                    sb.append(stringBuilder);
                    sb.append(",");
                  }
          
                  if (!clazz.equals(Object.class)) {
                    if (oldValue instanceof String) {
                      calcStringDiff(sb, (String) newValue, (String) oldValue, clazz);
                    } else {
                      String s = diffJavaBean(oldValue, newValue);
                      sb.append(s);
                      sb.append(",");
                    }
                  }
                }
              }
            }
          
            
          
          
            
          
            private static void calcStringDiff(
                StringBuilder sb, String newValue, String oldValue, Class<?> clazz) {
              Object ov = JSON.parseObject(oldValue, clazz);
              Object ne = JSON.parseObject(newValue, clazz);
              String s = diffJavaBean(ov, ne);
              sb.append(s);
              sb.append(",");
            }
          
            /**
             * 获取字段的属性值
             */
            private static <T> Object getFieldValue(T target, Class<?> targetClass, String name)
                throws IntrospectionException, IllegalAccessException, InvocationTargetException {
              PropertyDescriptor pd = new PropertyDescriptor(name, targetClass);
              Method getMethod = pd.getReadMethod(); // 获得get方法
              return getMethod.invoke(target);
            }
          
            private static StringBuilder changeCn(String cnFiledName, String oldValue, String newValue) {
              String format = String.format("字段[%s]从[%s]变成[%s]", cnFiledName, oldValue, newValue);
              return new StringBuilder(format);
            }
          
          
          
          
            
          
            @Data
            @NoArgsConstructor
            private class ObjectId {
          
              private Integer id;
            }
          

          测试

          字段[状态]从[3]变成[4]
          
          {"acceptDept":47,"acceptUser":71,"companyId":3,"createTime":1585707751000,"createUser":71,"customerOderName":"test","customerOderPhone":"12345678900","customerOrderId":84,"deleted":0,"groupId":2,"hotelServiceId":71,"id":321,"priority":1,"remark":"{\"consumerGoods\":[],\"consumerOrderName\":\"test\",\"consumerOrderPhone\":\"12345678900\",\"leavingMessages\":[{\"name\":\"张三\",\"time\":\"2020-04-01T10:22:31.031\",\"workOrderId\":321}]}","sn":"20200401000001","source":1,"status":4,"subscribe":0,"updateTime":1585707751000,"updateUser":71,"version":3}
          
          
          {"acceptDept":47,"companyId":3,"createTime":1585707751000,"createUser":71,"customerOderName":"test","customerOderPhone":"12345678900","customerOrderId":84,"deleted":0,"groupId":2,"hotelServiceId":71,"id":321,"priority":1,"remark":"{\"consumerGoods\":[],\"consumerOrderName\":\"test\",\"consumerOrderPhone\":\"12345678900\",\"leavingMessages\":[{\"name\":\"张三\",\"time\":\"2020-04-01T10:22:31.031\",\"workOrderId\":321}]}","sn":"20200401000001","source":1,"status":3,"subscribe":0,"updateTime":1585707751000,"updateUser":71,"version":2}
            撰写回答

            登录后参与交流、获取后续更新提醒

            相似问题
            推荐文章