2012-08-29 58 views
4

我正在尋找Java中的通用實用程序,它可以幫助我爲兩個對象(相同類型)創建差異報告。Java對象差異實用程序

舉例來說,如果我的階級結構是:

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

class B { 
float p3; 
} 

我希望報表B型A的/ w的兩個對象(比如,A1和A2),具體如下: A1與A2

p1 : 'remove' 
p2 : 'change' 
b1.p3: 'add' 

其中,如果屬性在第二個對象中爲空,則設置'remove';如果屬性存在但具有不同值,則爲'change';如果屬性在第一個對象中爲null,則設置'add'。

它可能變得更加強硬/棘手的集合對象...

+0

使用反射。當然,定義內部對象會發生什麼變得很棘手。 – SJuan76

回答

1

我懷疑有一個通用的工具來做到這一點。

但是,這似乎並不難用Java反射API編寫。

可以使用

myClass.getFields(); 

所以你只要做一個比較深的枚舉類的字段。

0

使用apache ToStringBuilder創建2個對象的sting表示。然後比較字符串。

拿上這個討論一下:How to perform string Diffs in Java?

它包含的參考圖書館,在Java中執行文本區別。

0

您可以使用反射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){} 
    } 
} 
8

我創建了一個庫:https://github.com/SQiShER/java-object-diff

它使你比較的對象的樹形結構,並允許您通過訪問者模式遍歷節點。看看Getting Started頁面,看一些例子。它適用於幾乎任何類型的對象,並且可以處理儘可能多的嵌套層次。我甚至設法建立一個基於它的自動對象合併。

這樣的對象圖的打印版本看起來是這樣的:

Property at path '/contacts/item[Walter White]/middleName' has been added => [ Hartwell ] 
Property at path '/contacts/item[Jesse Pinkman]/middleName' has been added => [ Bruce ] 

我用它自己,它就像一個魅力。希望能幫助到你!

我不知道你的對象有多複雜,但通過反射手動執行它會很快失去控制。特別是當地圖和集合涉及時。

5

Javers是圖書館,做exacly你需要:

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中實現了存儲。

+0

如果我比較的兩個對象在內部有一個對象列表,我會看到這些不同嗎? javers可以比較什麼層級? – Deepak

1

看看我製作的這個圖書館。也許這可能是有用的人(支持任意深對象圖和收藏/地圖/陣列差異/補丁/比較)...

它應該是簡單的使用方法:

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

This is the link to github repo. (https://github.com/bojanv55/entity-sync-utils)