2011-07-06 44 views
10

同じタイプのオブジェクトが2つあります。Javaで2つのオブジェクトをマージする

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} 

このオブジェクトを1つのオブジェクトに結合するにはどうすればよいですか教えてください。

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

はあなたが、これは単一期待する内容を説明することはでき

public static void copyProperties(Object source, Object target) 

、クラスBeanUtilsおよび上記の方法を使用し、それを解決するために
は、オブジェクトが見えるように、「合併しましたか」? – Asaph

+1

'obj1.a =" George "と' obj2.a = "Lucas" '" merged "オブジェクトの中の' 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

'this.b'が' null'で、 'obj2からの同じarraylist 'を要求していないため、NullPointerExceptionが発生しました –

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

これは、独自のゲッターとセッターを持つ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

Nevermind。両方のオブジェクトがgetXXとそれに対応するsetXXを持っている限り、これは動作します。 getterおよびsetterを使用して値だけをコピーします。 –

+0

obj.getClass()。getDeclaredMethods()を使用してgetClass/setClassなどをスキップし、そのクラスまたは対応するインタフェースで定義されたメソッドを取得します。 – tarkeshwar

6

だけ収容ブールシンク:それは更新上のgetParameter()の戻り値を持つOBJの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 Frameworkを使用しています。私はプロジェクトで同じ問題に直面していました。私は、これは一例であり、

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 
    } 
} 
関連する問題