Java合并两个对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6591665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Merging two objects in Java
提问by tamilnad
I have two objects of same type.
我有两个相同类型的对象。
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}
Can you please let me know what is the best way to combine this objects into single object?
您能否让我知道将这些对象组合成单个对象的最佳方法是什么?
obj3 = {a = "hello"; b = (same arraylist from obj2); c = 10}
采纳答案by Crozin
Maybe something like
也许像
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
might return a new A
object instead of modifing current.
A.merge
可能会返回一个新A
对象而不是修改当前对象。
回答by Thiago Duarte
If you create getters and setters for the attributes, you can use the copyPropertiesmethod from Commons BeanUtils.
如果为属性创建 getter 和 setter,则可以使用Commons BeanUtils 中的copyProperties方法。
回答by Andreas Dolk
In your very special case it looks like you want a new object that takes the realvalues from both instances. Here is an implementation that will do that. The method should be add to class A
so that it can access the fields.
在您的非常特殊的情况下,您似乎想要一个从两个实例中获取真实值的新对象。这是一个可以做到这一点的实现。该方法应该添加到类中,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;
}
回答by Alex Martín Jiménez
This works as long as you have POJOs with their own getters and setters. The method updates objwith non-null values from update. It calls setParameter() on objwith the return value of getParameter() on update:
只要您拥有带有自己的 getter 和 setter 的 POJO,这就会起作用。该方法使用来自update 的非空值更新obj。它在obj上调用 setParameter() 并在update 时使用getParameter() 的返回值:
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();
}
}
}
}
回答by Abhay Singh
Just accommodating boolean sync. and case sensitive(camel notation)
只是适应布尔同步。并区分大小写(骆驼符号)
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;
}
回答by George Siggouroglou
I am using Spring Framework. I was facing the same issue on a project.
To solve it i used the class BeanUtilsand the above method,
我正在使用 Spring 框架。我在一个项目中遇到了同样的问题。
为了解决它,我使用了类BeanUtils和上述方法,
public static void copyProperties(Object source, Object target)
This is an example,
这是一个例子,
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
}
}
回答by Zon
Add this method to your POJO, then use it like myObject.merge(newObject)
. It uses generics to loop through your POJO's fields, so you don't mention any field names:
将此方法添加到您的 POJO 中,然后像myObject.merge(newObject)
. 它使用泛型循环遍历 POJO 的字段,因此您无需提及任何字段名称:
/**
* Fill current object fields with new object values, ignoring new NULLs. Old values are overwritten.
*
* @param newObject Same type object with new values.
*/
public void merge(Object newObject) {
assert this.getClass().getName().equals(newObject.getClass().getName());
for (Field field : this.getClass().getDeclaredFields()) {
for (Field newField : newObject.getClass().getDeclaredFields()) {
if (field.getName().equals(newField.getName())) {
try {
field.set(
this,
newField.get(newObject) == null
? field.get(this)
: newField.get(newObject));
} catch (IllegalAccessException ignore) {
// Field update exception on final modifier and other cases.
}
}
}
}
}
回答by Kartik Nigam
There is a dynamic solution to merge any two objects which require Reflection and Recursion.
有一个动态解决方案来合并任何两个需要反射和递归的对象。
public <T> T merge(T local, T remote, ArrayList<String> listOfClass)
throws IllegalAccessException, InstantiationException {
Class<?> clazz = local.getClass();
Object merged = clazz.newInstance();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
Object localValue = field.get(local);
Object remoteValue = field.get(remote);
if (localValue != null) {
if (listOfClass.contains(localValue.getClass().getSimpleName())) {
field.set(merged, this.merge(localValue, remoteValue, listOfClass));
} else {
field.set(merged, (remoteValue != null) ? remoteValue : localValue);
}
} else if (remoteValue != null) {
field.set(merged, remoteValue);
}
}
return (T) merged;
}
Variable Description:
变量说明:
- local: The object on to which the other will be merged
- remote: The object which will be merged to the local object
- listOfClass: The ArrayList of custom classes in the given object
- 本地:另一个将合并到的对象
- 远程:将合并到本地对象的对象
- listOfClass:给定对象中自定义类的 ArrayList
The function returns a merged object which is good to go.
该函数返回一个很好的合并对象。
Kudos! :)
荣誉!:)