gpt4 book ai didi

java - 如何在java中合并两个复杂的对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:40:55 25 4
gpt4 key购买 nike

我有两个 java 对象,我想将它们合并为一个对象。问题是这两个对象不包含普通原始类型属性(字段),它们包含复杂类型属性(如其他类型的对象和其他类型的对象列表)。

对象一:通过设置一些属性(字段)和返回

对象 2:通过设置一些属性(字段)返回,或者它可能返回它持有但对象 1 未返回的类型的新对象。

对象 1 和对象 2 的类型相同。

结果对象 3 = obj1 属性 + 如果与 obj1 类型相同则更新 obj 2 的属性 + 来自 obj2 的新更新对象

最佳答案

使用 spring 提供的 org.springframework.beans.BeanUtils 类很容易做到。或者 Apache Commons BeanUtils library我相信 Springs 版本基于或相同。

public static <T> T combine2Objects(T a, T b) throws InstantiationException, IllegalAccessException {
// would require a noargs constructor for the class, maybe you have a different way to create the result.
T result = (T) a.getClass().newInstance();
BeanUtils.copyProperties(a, result);
BeanUtils.copyProperties(b, result);
return result;
}

如果你不能或没有 noargs 构造函数,也许你只是传递结果

public static <T> T combine2Objects(T a, T b, T destination) {
BeanUtils.copyProperties(a, destination);
BeanUtils.copyProperties(b, destination);
return destination;
}

如果你不想复制 null 属性,你可以使用这样的东西:

public static void nullAwareBeanCopy(Object dest, Object source) throws IllegalAccessException, InvocationTargetException {
new BeanUtilsBean() {
@Override
public void copyProperty(Object dest, String name, Object value)
throws IllegalAccessException, InvocationTargetException {
if(value != null) {
super.copyProperty(dest, name, value);
}
}
}.copyProperties(dest, source);
}

嵌套对象解决方案

这里有一个更强大的解决方案。它支持嵌套对象复制,1+ 级深的对象将不再通过引用复制,而是复制嵌套对象或单独复制它们的属性。

/**
* Copies all properties from sources to destination, does not copy null values and any nested objects will attempted to be
* either cloned or copied into the existing object. This is recursive. Should not cause any infinite recursion.
* @param dest object to copy props into (will mutate)
* @param sources
* @param <T> dest
* @return
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static <T> T copyProperties(T dest, Object... sources) throws IllegalAccessException, InvocationTargetException {
// to keep from any chance infinite recursion lets limit each object to 1 instance at a time in the stack
final List<Object> lookingAt = new ArrayList<>();

BeanUtilsBean recursiveBeanUtils = new BeanUtilsBean() {

/**
* Check if the class name is an internal one
* @param name
* @return
*/
private boolean isInternal(String name) {
return name.startsWith("java.") || name.startsWith("javax.")
|| name.startsWith("com.sun.") || name.startsWith("javax.")
|| name.startsWith("oracle.");
}

/**
* Override to ensure that we dont end up in infinite recursion
* @param dest
* @param orig
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
@Override
public void copyProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException {
try {
// if we have an object in our list, that means we hit some sort of recursion, stop here.
if(lookingAt.stream().anyMatch(o->o == dest)) {
return; // recursion detected
}
lookingAt.add(dest);
super.copyProperties(dest, orig);
} finally {
lookingAt.remove(dest);
}
}

@Override
public void copyProperty(Object dest, String name, Object value)
throws IllegalAccessException, InvocationTargetException {
// dont copy over null values
if (value != null) {
// attempt to check if the value is a pojo we can clone using nested calls
if(!value.getClass().isPrimitive() && !value.getClass().isSynthetic() && !isInternal(value.getClass().getName())) {
try {
Object prop = super.getPropertyUtils().getProperty(dest, name);
// get current value, if its null then clone the value and set that to the value
if(prop == null) {
super.setProperty(dest, name, super.cloneBean(value));
} else {
// get the destination value and then recursively call
copyProperties(prop, value);
}
} catch (NoSuchMethodException e) {
return;
} catch (InstantiationException e) {
throw new RuntimeException("Nested property could not be cloned.", e);
}
} else {
super.copyProperty(dest, name, value);
}
}
}
};


for(Object source : sources) {
recursiveBeanUtils.copyProperties(dest, source);
}

return dest;
}

它有点快而且脏,但效果很好。由于它确实使用了递归并且存在无限递归的潜力,所以我确实将其放在了安全防范中。

关于java - 如何在java中合并两个复杂的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24865923/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com