有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在java中获得对象的两个数组列表的差异

我有一个员工列表,一些方法是添加/删除员工或编辑员工的属性

employee{id, name, age, grp}

其中id是标识符

我正在尝试按照以下格式获取旧列表和修改列表之间的所有差异:

Format of the output

我尝试了ObjectDifferBuilder,这是github(https://github.com/SQiShER/java-object-diff)的一个java工具,如下所示:

//actionDataList - Action list for printing the diffs at the end of process
DiffNode diff = ObjectDifferBuilder.buildDefault().compare(newList, oldList);

diff.visit(new DiffNode.Visitor() {
    @Override
    public void node(DiffNode node, Visit visit) {
        String fieldName = "emp.";

        if (node.hasChanges() && !node.hasChildren()) {
            node.canonicalSet(newAe, node.canonicalGet(newAe) + "*");
        }

        if (!(node.getPath() == null || node.getPath().getLastElementSelector().toHumanReadableString().isEmpty())) {
            fieldName += node.getPath().getLastElementSelector().toHumanReadableString();

            Object baseValue = node.canonicalGet(oldList);
            Object workingValue = node.canonicalGet(newList);

            if (baseValue == null && workingValue instanceof String) {
                //for new values inserted
                actionDataList.add(new ActionData(fieldName, "", String.valueOf(workingValue)));
            } else if (workingValue == null && baseValue instanceof String) {                   
                // for old values deleted
                actionDataList.add(new ActionData(fieldName, String.valueOf(baseValue), ""));
            }
        }
    }
});

但仍然没有得到适当的输出


共 (1) 个答案

  1. # 1 楼答案

    在这里,我做了如下的变通方法。希望这对别人有帮助。(参考代码中的注释)

    Map<String, Employee> entityById = 
    oldList.stream().collect(Collectors.toMap(Employee::getId, 
    Function.identity())); //changed oldList to Map
    
      for (Employee entity : newList) //iterate new list to check the old values
      {
         if (entityById.containsKey(entity.getId())) // check for updated record
         {
            printActionRecord(entityById.get(entity.getId()), entity, actionDataList,"UPDATED");
            entityById.remove(entity.getId());
         }
         else // check for newly inserted record
         {
            printActionRecord(entityById.get(entity.getId()), entity, actionDataList,"INSERTED");
         }
      }
      if (!entityById.isEmpty()) // check for deleted record from new list( but existing in oldlist)
      {
         entityById.forEach((key, entity) -> {
            printActionRecord(entityById.get(entity.getId()), entity, actionDataList,"DELETED");
         });
      }
    

    在上面,我可以计算出新列表中更新/创建/删除的记录。在我找到这个之后,我将把那个记录和旧记录一起传递(仅在更新的情况下)以获得差异。通过DiffNode diff = ObjectDifferBuilder.buildDefault().compare(newobj, oldobj);它为字段中的每个更改提供了记录

    //actionDataList - Action list for printing the diffs at the end of process
    DiffNode diff = ObjectDifferBuilder.buildDefault().compare(newObject, oldObject);
    
    diff.visit(new DiffNode.Visitor() {
    @Override
    public void node(DiffNode node, Visit visit) {
        String fieldName = "emp."; //it should be a variable for each type of field
        if (!(node.getPath() == null || node.getPath().getLastElementSelector().toHumanReadableString().isEmpty())) {
            fieldName += node.getPath().getLastElementSelector().toHumanReadableString();
    
            Object baseValue = node.canonicalGet(oldObject);
            Object workingValue = node.canonicalGet(newObject);
    
            if (baseValue == null && workingValue instanceof String) {
                //for new values inserted
                actionDataList.add(new ActionData(fieldName, "", String.valueOf(workingValue)));
            } else if (workingValue == null && baseValue instanceof String) {                   
                // for old values deleted
                actionDataList.add(new ActionData(fieldName, String.valueOf(baseValue), ""));
            } else { // print updates
                actionDataList.add(new ActionData(fieldName, String.valueOf(baseValue), String.valueOf(workingValue))); 
            }
        }
    }
    });
    

    然后,我们可以打印actionDataList值

    for(ActionData a: actionDataList){
        System.out.println("Field:"+ a.getFieldName()+ " Old Value:"+a.getOldValue()+"  NewValue:"+a.getNewValue());
    }
    

    希望这有帮助