欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

对象属性深拷贝工具DozerBeanMapper封装

程序员文章站 2022-06-08 17:16:30
...

前段时间我分享了两个对象属性拷贝工具,Spring的BeanUtils以及CGLIB的BeanCopier的封装类,之所以封装就是因为直接使用原始的类的话,使用方式不够统一,且略微复杂。上面两个工具都是浅拷贝,今天分享的则是深拷贝。
感兴趣的移步:
封装BeanCopier工具,支持单个对象以及列表拷贝,超高性能简单实用
代码片段:BeanUtils.copyProperties扩展复制列表

深拷贝DozerBeanMapper封装

import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 单个对象属性拷贝、列表对象拷贝
 * <p>
 * 拷贝类型:深拷贝
 * 浅拷贝见CopierUtil
 *
 * @author itoak
 */
public class MapperUtil {

    /**
     * 单个对象属性拷贝
     *
     * @param source 源对象
     * @param clazz  目标对象Class
     * @param <T>    目标对象类型
     * @param <M>    源对象类型
     * @return 目标对象
     */
    public static <T, M> T copyProperties(M source, Class<T> clazz) {
        if (Objects.isNull(source) || Objects.isNull(clazz))
            throw new IllegalArgumentException();
        Mapper mapper = BeanHolder.MAPPER.getMapper();
        return mapper.map(source, clazz);
    }

    /**
     * 列表对象拷贝
     *
     * @param sources 源列表
     * @param clazz   源列表对象Class
     * @param <T>     目标列表对象类型
     * @param <M>     源列表对象类型
     * @return 目标列表
     */
    public static <T, M> List<T> copyObjects(List<M> sources, Class<T> clazz) {
        if (Objects.isNull(sources) || Objects.isNull(clazz) || sources.isEmpty())
            throw new IllegalArgumentException();
        return Optional.of(sources)
                .orElse(new ArrayList<>())
                .stream().map(m -> copyProperties(m, clazz))
                .collect(Collectors.toList());
    }

    /**
     * 单例
     * <p>
     * DozerBeanMapper使用单例,有利于提高程序性能
     */
    private enum BeanHolder {
        MAPPER;

        private DozerBeanMapper mapper;

        BeanHolder() {
            this.mapper = new DozerBeanMapper();
        }

        public DozerBeanMapper getMapper() {
            return mapper;
        }
    }
}

深浅拷贝的含义应该不用多说,至于工具的选择,需要开发自己去选择,如果一个对象只包含基本字段属性,可以优先考虑使用BeanCopier,但是这个工具需要依赖CGLIB包,如果不想依赖,则考虑使用Spring的BeanUtils,如果对象包含自定义类字段属性,再拷贝的时候推荐使用DozerBeanMapper工具。