Java对象差异实用程序

Java对象差异实用程序,java,diff,Java,Diff,我正在寻找Java中的通用实用程序,它可以帮助我为两个对象(相同类型)创建差异报告 例如,如果我的类结构是: class A { int p1; string p2; B b1; } class B { float p3; } 我想要一份包含两个a型对象(比如a1和a2)的报告,如下所示: a1对a2 p1 : 'remove' p2 : 'change' b1.p3: 'add' 其中,如果第二个对象中的属性为null,则设置“移除”;如果属性存在但具有不同的值,则设置“更

我正在寻找Java中的通用实用程序,它可以帮助我为两个对象(相同类型)创建差异报告

例如,如果我的类结构是:

class A {
  int p1;
  string p2;
  B b1;
}

class B {
 float p3;
}
我想要一份包含两个a型对象(比如a1和a2)的报告,如下所示: a1对a2

p1 : 'remove'
p2 : 'change'
b1.p3: 'add'
其中,如果第二个对象中的属性为null,则设置“移除”;如果属性存在但具有不同的值,则设置“更改”;如果第一个对象中的属性为null,则设置“添加”


收集对象可能会变得更难/更复杂…

我怀疑是否有通用的实用程序可以做到这一点

但是,使用java反射API编写这似乎并不困难

可以使用枚举类的字段

myClass.getFields();

因此,您只需进行深入比较。

使用apache
ToStringBuilder创建两个对象的sting表示。然后比较字符串

看看这个讨论:


它包含对在java中执行文本差异的库的引用。

您可以使用反射API来实现它

我没有给出完整的代码。但这是你可以开始的一种方式

class Testapp {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
        a1.b1.p3 = 1;
        a1.p1 = 2;
        a1.p2 = "Hi";

        a2.b1.p3 = 1;
        a2.p1 = 3;
        a2.p2 = "Hi";

        Compare c = new Compare<A>(a1, a2);
        c.compare();
    }
}

class A
{
    int p1;
    String p2;
    B b1;
    A() {
        b1 = new B();
    }
}

class B {
    float p3;
}


class Compare<T extends Object> {
    T a;
    T b;
    public Compare(T a, T b)
    {
        this.a = a;
        this.b = b;
    }
    public void compare()
    {
        try
        {
            Field[] fields = a.getClass().getDeclaredFields();

            for (Field field : fields) {
                if(field.get(a)==field.get(b)){
                    //do something
                }
            }
        }catch(Exception e){}
    }
}
类Testapp{
公共静态void main(字符串[]args){
a1=新的A();
a2=新的A();
a1.b1.p3=1;
a1.p1=2;
a1.p2=“你好”;
a2.b1.p3=1;
a2.p1=3;
a2.p2=“你好”;
比较c=新的比较(a1,a2);
c、 比较();
}
}
甲级
{
int-p1;
字符串p2;
B b1;
(){
b1=新的B();
}
}
B类{
浮动p3;
}
班级比较{
Tα;
tb;
公共比较(TA、TB)
{
这个a=a;
这个.b=b;
}
公共空间比较()
{
尝试
{
Field[]fields=a.getClass().getDeclaredFields();
用于(字段:字段){
if(field.get(a)=field.get(b)){
//做点什么
}
}
}捕获(例外e){}
}
}

我为此创建了一个库:

它构建了比较对象的树结构,并允许您通过访问者模式遍历节点。看看这页,看看一些例子。它适用于几乎任何类型的对象,可以处理任意多个嵌套级别。我甚至成功地基于它构建了一个自动对象合并

此类对象图的打印版本如下所示:

Property at path '/contacts/item[Walter White]/middleName' has been added => [ Hartwell ]
Property at path '/contacts/item[Jesse Pinkman]/middleName' has been added => [ Bruce ]
我自己也在用它,它就像一个符咒。希望有帮助

我不知道你的对象有多复杂,但是通过反射手动操作会很快失控。尤其是当涉及到地图和收藏时。

是一个能满足您需求的图书馆:

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

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序列化程序和反序列化程序,并进行了更改,还在mongoDB中实现了存储

看看我制作的这个库。也许它对某些人有用(支持diff/patch/compare与任意深度对象图和集合/映射/数组)

它应该易于使用:

GrandChildEntity gce1 = new GrandChildEntity(1);
GrandChildEntity gce2 = new GrandChildEntity(2);

Diff diff = new Diff.Builder().build();
Patch patch = new Patch.Builder().build();
Compare compare = new   Compare.Builder().build();

Element<Name, GrandChildEntity> diffElement = diff.diff(gce1, gce2);
GrandChildEntity patchedEntity = patch.patch(new GrandChildEntity(1), diffElement);
boolean areEqual = compare.compare(patchedEntity, new GrandChildEntity(2));
孙子实体gce1=新孙子实体(1);
孙子实体gce2=新孙子实体(2);
Diff Diff=新的Diff.Builder().build();
补丁补丁=新补丁.Builder().build();
Compare Compare=新建Compare.Builder().build();
元素差异=差异(gce1,gce2);
孙子实体patchedEntity=patch.patch(新孙子实体(1),differention);
布尔值areEqual=compare.compare(patchedEntity,新实体(2));

使用反射。当然,定义内部对象会发生什么是很困难的。如果我比较的两个对象内部有一个对象列表,我会看到这些差异吗?javers可以比较的等级是什么?