繁体   English   中英

如何在Java中获取对象的两个ArrayList的差异

[英]How to get diff of two ArrayList of Object in java

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

employee{id, name, age, grp}

id是标识符。

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

输出格式

which is a java tool from github( https://github.com/SQiShER/java-object-diff ) like below: 我尝试了 ,它是来自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), ""));
            }
        }
    }
});

但是仍然无法获得正确的输出。

在这里,我做了如下的解决方法。 希望这对某人有帮助。 (请参阅代码中的注释)

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());
}

希望这可以帮助。

首先,我认为您需要完善您要尝试做的事情。

您需要两个列表之间的差异,其中一个列表是通过对原始列表的更改生成的。 除了它们不是真正的列表,它们是结构化记录的列表(如数据库表)。

对(emp.age,DELETE,33)意味着什么? 这是否意味着所有33岁的员工都被罢免了? 它实际上是跨越3行的特定员工罢免的一部分吗?

迫使自己发现的一种方法是编写一个称为ListChange的接口,并使它的子类封装更改的配置。 然后,您可以获取一个List并将一个DeleteChange应用于该List ,看看是否达到所需的输出。

一旦有了这样的结构,就几乎拥有了所需的所有信息,但是格式错误。 除了简单地应用更改外,还可以添加一些修改来存储原始记录和更改后的记录,但前提是要更改记录。 这将使您的“记录已更改”。

为了将它们链接在一起,获得正确的输出将需要另外一个元素,即“起始”记录。 这样,您就可以将操作的“已更改记录”与操作的“开始”记录进行比较。 如果您将记录更改回其起始记录,则应放弃更改条目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM