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"
        }
    ]
}
阅读 9.5k
4 个回答

究极无敌最终版!!!

方案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来判断一下是不是遍历到了最后一个

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

  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}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题