2015-09-28 16 views
0

我遇到了一個問題,以更新現有數據,無論用戶做了什麼更改。比較兩個對象中的字段並將其中的一個更新到另一箇中

例如,我有一個公司對象,如下

public class Company { 

    private String id; 

    private String name; 

    private String url; 

    //Getter and setter..... 
} 

現在我有一個數據一個公司的實例如下

Company company = new Company(); 
company.setId("id12345678"); 
company.setName("company Old Name"); 
company.setUrl("company Old Url"); 

現在用戶創建另一個公司實例只是爲了更新nameurl已有Company

Company newCompany = new Company(); 
newCompany.setId("id12345678"); 
newCompany.setName("company New Name"); 
newCompany.setUrl("company New Url"); 

可以看到,Company的新實例與舊版本具有相同的Id,但具有不同的nameurl

是否有任何實用工具/庫可以簡單地找到這兩個對象之間的所有區別並將更改應用到company實例? (真的不希望編寫代碼來手動比較每個字段)

喜歡的東西

company = AwesomeLibraryUtils.compareAndApplyDifferences(company, newCompany); 

在此之後,company實例保持相同ID但隨着namenewCompanyurl所有的新值實例。

謝謝。

+1

不知道,但看看這是否符合您的要求https://github.com/SQiShER/java-object-diff – virendrao

+1

我會留在這裏:[*「問題要求我們推薦或找到一本書,工具,軟件庫,教程或其他非現場資源對於堆棧溢出而言是偏離主題的,因爲它們傾向於吸引自以爲是的答案和垃圾郵件。「*](http://stackoverflow.com/help/on-topic)。 – Tom

+0

感謝virendrao,我看看這個。 – jasonfungsing

回答

1

有沒有真正的實用工具,可以「找到並應用」的差異(據我所知),但是,沒有反射(如其他說),如Apache比較器(這是一個強大的類)。

https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.1/org/apache/commons/collections/ComparatorUtils.html

至於「施加的差異」,也有在Apache的一種工具(BeanUtils的這段時間):http://commons.apache.org/proper/commons-beanutils/其爲「copyProperties(Object o1, Object o2)」 wihchi將所有屬性(字段)從一個對象複製到另一個。

所以,你只需比較對象,如果他們是差異,複製一個到另一個。

除了性能問題,我不明白爲什麼你只複製不同的字段(因爲如果你複製的字段是相同的,那麼就不會有任何區別)。如果您只需複製不同的字段,我想您必須製作自己的工具。

+0

感謝您的回答。基本上我可以通過使用Apache Commons中的兩個utils來實現此目的。 – jasonfungsing

0

您應該覆蓋equals()方法。之後,您將能夠檢查條件company.equals(newCompany)

着名的IDE支持自動生成equals方法。例如,IDEA將其生成爲:

@Override 
public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 

    Company company = (Company) o; 

    if (id != null ? !id.equals(company.id) : company.id != null) return false; 
    if (name != null ? !name.equals(company.name) : company.name != null) return false; 
    return !(url != null ? !url.equals(company.url) : company.url != null); 

} 
+0

請閱讀我的問題:是否有任何實用工具/庫可以簡單地找到這兩個對象之間的所有區別並將更改應用到公司實例? – jasonfungsing

2

使用反映來查找公司和newCompany中的獲取者和設置者的所有結果。

基本上,我在這裏做如下幾點:

1.放入newCompany干將的所有結果到一個名爲HM HashMap中。

2.掃描公司中的獲取者結果。如果hm不包含公司中的任何一個獲得者的結果,那麼這兩個公司被認爲是不同的。

3.如果兩家公司不同,請將公司中的值設置爲newCompany中的值。

public static void compareAndApplyDifferences(Object o1, Object o2) { 
    if(!o1.getClass().equals(o2.getClass())) { 
     return; 
    } 
    // check if the result of getters in o1 and o2 are different 
    boolean isDiff = false; 
    Class<? extends Object> c1 = o1.getClass(); 
    Class<? extends Object> c2 = o2.getClass(); 
    Method[] methods1 = c1.getMethods(); 
    Method[] methods2 = c2.getMethods(); 
    Map<String, Object> hm = new HashMap<String, Object>(); 
    for (Method method2 : methods2) { 
     if (isGetter(method2)) { 
      try { 
       Object getterResult = method2.invoke(o2); 
       hm.put(method2.getName().substring(3), getterResult); 
      } catch (IllegalAccessException e) { 
      } catch (IllegalArgumentException e) { 
      } catch (InvocationTargetException e) { 
      } 
     } 
    } 
    for (Method method1 : methods1) { 
     if (isGetter(method1)) { 
      try { 
       String getterResult = (String) method1.invoke(o1); 
       if (!hm.containsValue(getterResult)) { 
        isDiff = true; 
        break; 
       } 
      } catch (IllegalAccessException e) { 
      } catch (IllegalArgumentException e) { 
      } catch (InvocationTargetException e) { 
      } 
     } 
    } 

    if (isDiff) { 
     // set the values in o1 as the values in o2 
     for (Method method1 : methods1) { 
      if (isSetter(method1)) { 
       try { 
        method1.invoke(o1, hm.get(method1.getName().substring(3))); 
       } catch (IllegalAccessException e) { 
       } catch (IllegalArgumentException e) { 
       } catch (InvocationTargetException e) { 
       } 
      } 
     } 
    } else { 
     return; 
    } 
} 

private static boolean isGetter(Method method) { 
    if (!method.getName().startsWith("get")) 
     return false; 
    if (method.getParameterTypes().length != 0) 
     return false; 
    if (void.class.equals(method.getReturnType())) 
     return false; 
    return true; 
} 

private static boolean isSetter(Method method) { 
    if (!method.getName().startsWith("set")) 
     return false; 
    if (method.getParameterTypes().length != 1) 
     return false; 
    return true; 
} 

這裏是我的方案的論證:

public static void main(String[] args) { 

    Company company = new Company(); 
    company.setId("id12345678"); 
    company.setName("company Old Name"); 
    company.setUrl("company Old Url"); 

    Company newCompany = new Company(); 
    newCompany.setId("id12345678"); 
    newCompany.setName("company New Name"); 
    newCompany.setUrl("company New Url"); 

    AwesomeLibraryUtils.compareAndApplyDifferences(company, newCompany); 

    System.out.println(company.getId()); // id12345678 
    System.out.println(company.getName()); // company New Name 
    System.out.println(company.getUrl()); // company New Url 
} 
+0

感謝您的回答。有這個工具很好,我會深入研究這個。對於來自第三方的現有庫的「快速獲勝」,我選擇了另一個作爲答案。對此感到抱歉:-) – jasonfungsing

相關問題