2011-07-06 91 views
10

我有兩個相同類型的對象。在Java中合併兩個對象

Class A{ 
    String a; 
    List b; 
    int c; 
} 

A obj1= new A(); 
A obj2 = new A(); 

obj1 => {a = "hello";b=null;c=10} 
obj2 => {a=null;b= new ArrayList();c=default value} 

您能否讓我知道將這些對象合併爲單個對象的最佳方法是什麼?

obj3 = {a = "hello";b=(same arraylist from obj2);c=10} 
+2

你能描述你所期望的這單「合併」對象是什麼樣子? – Asaph

+1

如果'obj1.a =「George」'和'obj2.a =「Lucas」'「合併」對象中obj3.a的值應該是多少? – Asaph

+0

您可以假設這些對象是互斥的 – tamilnad

回答

8

也許像

class A { 
    String a; 
    List<..> b; 
    int c; 

    public void merge(A other) { 
     this.a = other.a == null ? this.a : other.a; 
     this.b.addAll(other.b); 
     this.c = other.c == 0 ? this.c : other.c; 
    } 
} 

A a1 = new A(); 
A a2 = new A(); 

a1.a = "a prop"; 
a2.c = 34; 

a1.merge(a2); 

A.merge可能會返回,而不是對矯正當前新A對象。

+0

這就是我要推薦的 - 您必須在某處清楚地編寫規則 - 您不想爲代碼添加像反射一樣的「魔術」,除非它絕對是最後一個度假村 - 這種情況並不困難。 –

+3

NullPointerException因爲'this.b'可能是'null',它不符合'b'的相同arraylist obj2請求' –

2

如果爲屬性創建getter和setter,可以使用從共享的BeanUtils的copyProperties方法。

2

在你非常特殊的情況下,它看起來像你想要一個新的對象,從兩個實例中獲取真實值值。這是一個將會這樣做的實現。該方法應該添加到類A,以便它可以訪問字段。

public A specialMergeWith(A other) { 
    A result = new A(); 

    result.a = (a == null ? other.a : a); 
    result.b = (b == null ? other.b : b); 
    result.c = (c == DEFAULT_VALUE ? other.c : c); 

    return result; 
} 
21

只要你擁有自己的getter和setter的POJO,它就可以工作。該方法使用來自更新的非空值更新obj

public void merge(Object obj, Object update){ 
    if(!obj.getClass().isAssignableFrom(update.getClass())){ 
     return; 
    } 

    Method[] methods = obj.getClass().getMethods(); 

    for(Method fromMethod: methods){ 
     if(fromMethod.getDeclaringClass().equals(obj.getClass()) 
       && fromMethod.getName().startsWith("get")){ 

      String fromName = fromMethod.getName(); 
      String toName = fromName.replace("get", "set"); 

      try { 
       Method toMetod = obj.getClass().getMethod(toName, fromMethod.getReturnType()); 
       Object value = fromMethod.invoke(update, (Object[])null); 
       if(value != null){ 
        toMetod.invoke(obj, value); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
+0

感謝您的回答...但我的對象有很多原始類型,如int ,浮動等它也有List作爲成員。 – tamilnad

+0

沒關係。只要這兩個對象都有getXX及其對應的setXX,這就可以工作。它將只使用getter和setter來複制值。 –

+0

使用obj.getClass()。getDeclaredMethods()來跳過getClass/setClass等,並獲得在該類或相應接口中定義的方法。 – tarkeshwar

6

只是容納布爾同步:它更新呼籲OBJ使用getParameter()的返回值的setParameter()。和區分大小寫(駱駝符號)

public boolean merge(Object obj){ 

    if(this.equals(obj)){ 
     return false; 
    } 

    if(!obj.getClass().isAssignableFrom(this.getClass())){ 
     return false; 
    } 

    Method[] methods = obj.getClass().getMethods(); 

    for(Method fromMethod: methods){ 
     if(fromMethod.getDeclaringClass().equals(obj.getClass()) 
       && (fromMethod.getName().matches("^get[A-Z].*$")||fromMethod.getName().matches("^is[A-Z].*$"))){ 

      String fromName = fromMethod.getName(); 
      String toName ; 
      if(fromName.matches("^get[A-Z].*")){ 
       toName = fromName.replace("get", "set"); 
      }else{ 
       toName = fromName.replace("is", "set"); 
      } 

      try { 
       Method toMetod = obj.getClass().getMethod(toName, fromMethod.getReturnType()); 
       Object value = fromMethod.invoke(this, (Object[])null); 
       if(value != null){ 
        toMetod.invoke(obj, value); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    return true; 
} 
5

我正在使用Spring框架。我在一個項目上面臨同樣的問題。
爲了解決它,我使用的類BeanUtils和上面的方法,

public static void copyProperties(Object source, Object target) 

這是一個例子,

public class Model1 { 
    private String propertyA; 
    private String propertyB; 

    public Model1() { 
     this.propertyA = ""; 
     this.propertyB = ""; 
    } 

    public String getPropertyA() { 
     return this.propertyA; 
    } 

    public void setPropertyA(String propertyA) { 
     this.propertyA = propertyA; 
    } 

    public String getPropertyB() { 
     return this.propertyB; 
    } 

    public void setPropertyB(String propertyB) { 
     this.propertyB = propertyB; 
    } 
} 

public class Model2 { 
    private String propertyA; 

    public Model2() { 
     this.propertyA = ""; 
    } 

    public String getPropertyA() { 
     return this.propertyA; 
    } 

    public void setPropertyA(String propertyA) { 
     this.propertyA = propertyA; 
    } 
} 

public class JustATest { 

    public void makeATest() { 
     // Initalize one model per class. 
     Model1 model1 = new Model1(); 
     model1.setPropertyA("1a"); 
     model1.setPropertyB("1b"); 

     Model2 model2 = new Model2(); 
     model2.setPropertyA("2a"); 

     // Merge properties using BeanUtils class. 
     BeanUtils.copyProperties(model2, model1); 

     // The output. 
     System.out.println("Model1.propertyA:" + model1.getPropertyA(); //=> 2a 
     System.out.println("Model1.propertyB:" + model1.getPropertyB(); //=> 1b 
    } 
}