对象,集合 高效率拷贝


/**
 * 对Cglib BeanCopier进行封装 方便进行bean复制
 * 引用自:https://segmentfault.com/a/1190000006922799
 * @author:
 * @date: 2019/11/7 17:55
 */
public abstract class WrappedBeanCopier {
    private static final Map<String, BeanCopier> beanCopierCache = new ConcurrentHashMap<>();
    private static final Map<String, ConstructorAccess<?>> constructorAccessCache = new ConcurrentHashMap<>();

    /**
     * 拷贝泛型对象
     *
     * <pre>
     * Page&lt;ProductLimitPrice&gt; src = new Page<>();
     * Page&lt;ProductLimitPriceDTO&gt; dist = WrappedBeanCopier.copyProperties(src, new TypeReference&lt;Page&lt;ProductLimitPriceDTO&gt;&gt;(){});
     * </pre>
     */
    public static <T> T copyProperties(Object source, TypeReference<T> targetType) {
        if (source == null) return null;
        return TypeUtils.cast(source, targetType.getType(), ParserConfig.getGlobalInstance());
    }

    /**
     * 拷贝普通对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T copyProperties(Object source, Class<T> targetClass) {
        if (source == null) return null;
        ConstructorAccess<?> constructorAccess = getConstructorAccess(targetClass);
        T t = (T) constructorAccess.newInstance();
        copyProperties(source, t);
        return t;
    }

    /**
     * 拷贝List
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> copyPropertiesOfList(List<?> sourceList, Class<T> targetClass) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return Collections.emptyList();
        }
        ConstructorAccess<?> constructorAccess = getConstructorAccess(targetClass);
        List<T> resultList = new ArrayList<>(sourceList.size());
        for (Object o : sourceList) {
            T t = null;
            try {
                t = (T) constructorAccess.newInstance();
                copyProperties(o, t);
                resultList.add(t);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return resultList;
    }

    private static void copyProperties(Object source, Object target) {
        BeanCopier copier = getBeanCopier(source.getClass(), target.getClass());
        copier.copy(source, target, null);
    }

    private static BeanCopier getBeanCopier(Class<?> sourceClass, Class<?> targetClass) {
        String beanKey = generateKey(sourceClass, targetClass);
        BeanCopier copier = null;
        if (!beanCopierCache.containsKey(beanKey)) {
            copier = BeanCopier.create(sourceClass, targetClass, false);
            beanCopierCache.put(beanKey, copier);
        } else {
            copier = beanCopierCache.get(beanKey);
        }
        return copier;
    }

    private static String generateKey(Class<?> class1, Class<?> class2) {
        return class1.toString() + class2.toString();
    }

    private static ConstructorAccess<?> getConstructorAccess(Class<?> targetClass) {
        ConstructorAccess<?> constructorAccess = constructorAccessCache.get(targetClass.toString());
        if(constructorAccess != null) {
            return constructorAccess;
        }
        try {
            constructorAccess = ConstructorAccess.get(targetClass);
//            constructorAccess.newInstance();
            constructorAccessCache.put(targetClass.toString(),constructorAccess);
        } catch (Exception e) {
            throw new RuntimeException("Create new instance of "+targetClass+" failed: "+e.getMessage());
        }
        return constructorAccess;
    }

}
  Page<ProjectInfoDTO> projectInfoDTOPage = WrappedBeanCopier.copyProperties(pageResult, new TypeReference<Page<ProjectInfoDTO>>() {
        });

### 使用 `BeanUtils.copyProperties` 拷贝集合 当涉及到使用 Java 的 `BeanUtils.copyProperties` 来拷贝集合时,需要注意该方法本身并不直接支持集合类型的复制。此方法主要用于单个对象之间的属性拷贝[^2]。 为了实现列表或集合中多个对象的属性拷贝操作,通常的做法是遍历集合中的每一个元素并调用 `BeanUtils.copyProperties` 进行逐项处理: ```java import org.apache.commons.beanutils.BeanUtils; import java.util.ArrayList; import java.util.List; public class CopyUtil { public static <T, V> List<V> copyList(List<T> sourceList, Class<V> targetClass) throws Exception { List<V> resultList = new ArrayList<>(); for (T item : sourceList) { V newItem = targetClass.getDeclaredConstructor().newInstance(); BeanUtils.copyProperties(newItem, item); resultList.add(newItem); } return resultList; } } ``` 上述代码展示了如何创建一个新的目标类实例,并通过循环迭代原集合内的每一项来进行属性值的转移。这种方法适用于简单的 POJO 类型转换,在实际应用中应确保源对象和目的对象具有相同的属性名称以便自动映射生效[^3]。 另外值得注意的是,因为 `BeanUtils.copyProperties()` 是基于反射机制工作的,所以在高并发环境下或者大数据量情况下可能会影响程序效率。如果性能成为一个问题,则建议探索更为高效的替代方案,比如手动编写拷贝逻辑或是利用第三方库如 MapStruct 或 Dozer 等专门用于对象间映射的框架[^4]。 #### 性能优化提示 - 对于频繁使用的实体类之间转化,可以预先定义好映射关系减少运行期计算开销; - 如果两个类结构非常相似甚至完全一致,考虑采用序列化方式完成深克隆; - 针对特定业务需求定制化的解决方案往往能够带来更好的执行速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值