有没有一个Java库可以“比较”两个对象?

2022-08-31 09:53:36

有没有一个类似于Unix程序diff的Java实用程序库,但是对于对象?我正在寻找可以比较相同类型的两个对象并生成表示它们之间差异的数据结构的东西(并且可以递归地比较实例变量中的差异)。我不是在寻找文本差异的Java实现。我也不是在寻找如何使用反射来做到这一点的帮助。

我维护的应用程序具有此功能的脆弱实现,该功能有一些糟糕的设计选择,需要重写,但如果我们可以使用现成的东西,那就更好了。

以下是我正在寻找的那种东西的一个例子:

SomeClass a = new SomeClass();
SomeClass b = new SomeClass();

a.setProp1("A");
a.setProp2("X");

b.setProp1("B");
b.setProp2("X");

DiffDataStructure diff = OffTheShelfUtility.diff(a, b);  // magical recursive comparison happens here

比较后,实用程序会告诉我“prop1”在两个对象之间是不同的,而“prop2”是相同的。我认为DiffDataStructure成为一棵树是最自然的,但如果代码可靠,我不会挑剔。


答案 1

可能有点晚了,但我和你一样处于同样的情况,最终为你的用例创建了自己的库。由于我被迫自己想出一个解决方案,我决定在Github上发布它,以免其他人的辛勤工作。你可以在这里找到它:https://github.com/SQiShER/java-object-diff

--- 编辑 ---

下面是一个基于 OP 代码的小用法示例:

SomeClass a = new SomeClass();
SomeClass b = new SomeClass();

a.setProp1("A");
a.setProp2("X");

b.setProp1("B");
b.setProp2("X");

DiffNode diff = ObjectDifferBuilder.buildDefault().compare(a, b);

assert diff.hasChanges();
assert diff.childCount() == 1;
assert diff.getChild('prop1').getState() == DiffNode.State.CHANGED;

答案 2

http://javers.org 库可以满足您的需求:具有诸如compare(Object leftGraph,Object rightGraph)之类的方法,可以返回Diff对象。Diff 包含更改列表(引用更改、值更改、属性更改),例如

given:
DummyUser user =  dummyUser("id").withSex(FEMALE).build();
DummyUser user2 = dummyUser("id").withSex(MALE).build();
Javers javers = JaversTestBuilder.newInstance()

when:
Diff diff = javers.compare(user, user2)

then:
diff.changes.size() == 1
ValueChange change = diff.changes[0]
change.leftValue == FEMALE
change.rightValue == MALE

它可以处理图形中的循环。

此外,您还可以获得任何图形对象的快照。Javers具有JSON序列化程序和反序列化程序来快照,以及更改,因此您可以轻松地将它们保存在数据库中。使用此库,您可以轻松实现用于审核的模块。


推荐