Java 拷贝对象集合属性 集合泛型不一致 也可拷贝

Demo 对象如图

 

 我们同时创建三个相同属性Vo对象

 

 当我们使用BeanUtils进行拷贝时,会发现这样的问题

public static void main(String[] args) {
        Student student = new Student();
        student.setStudentName("大明");
        List<Student> studentList = new ArrayList<>();
        studentList.add(student);

        Teacher teacher = new Teacher();
        teacher.setTeacherName("张老师");
        teacher.setStudentList(studentList);
        List<Teacher> teacherList = new ArrayList<>();
        teacherList.add(teacher);

        School school = new School();
        school.setSchoolName("三中");
        school.setTeacherList(teacherList);

        SchoolVo schoolVo = new SchoolVo();
        BeanUtils.copyProperties(school, schoolVo);
        System.out.println("schoolVo = " + schoolVo);

        List<TeacherVo> teacherList1 = schoolVo.getTeacherList();
        TeacherVo teacherVo = teacherList1.get(0);
        List<StudentVo> studentList1 = teacherVo.getStudentList();
        System.out.println("studentList1 = " + studentList1);
        System.out.println("teacherList1 = " + teacherList1);

    }

 SchoolVo和School 相同的属性的值是拷贝过去了,但是SchoolVo的teacherList的泛型并不是TeacherVo 而是Teacher 所以当我们获取集合中的TeacherVo对象就会报错

 针对上述这种情形,我们可以使用 OrikaMapper进行拷贝 

pom

    <dependency>
      <groupId>ma.glasnost.orika</groupId>
      <artifactId>orika-core</artifactId>
      <version>1.4.1</version>
    </dependency>

 封装的Utils

public class OrikaMapperUtils {

    private static MapperFacade mapper;

    static {
        MapperFactory factory = new DefaultMapperFactory.Builder().build();
        mapper = factory.getMapperFacade();
    }

    private OrikaMapperUtils() {
    }

    /**
     * 简单的复制出新类型对象.
     * <p>
     * 内部实现是通过source.getClass() 获得源Class
     */
    public static <S, D> D map(S source, Class<D> destinationClass) {
        return mapper.map(source, destinationClass);
    }

    /**
     * 极致性能的复制出新类型对象.
     * <p>
     * 预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存Type类型,在此处传入
     */
    public static <S, D> D map(S source, Type<S> sourceType, Type<D> destinationType) {
        return mapper.map(source, sourceType, destinationType);
    }


    /**
     * 简单的复制出新对象列表到ArrayList
     * <p>
     * 不建议使用{@link MapperFacade#mapAsList(Object[], Class)}} 接口, sourceClass需要在遍历每一个元素的时候反射,实在有点慢
     */
    public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<S> sourceClass, Class<D> destinationClass) {
        return mapper.mapAsList(sourceList, TypeFactory.valueOf(sourceClass), TypeFactory.valueOf(destinationClass));
    }

    /**
     * 极致性能的复制出新类型对象到ArrayList.
     * <p>
     * 预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存Type类型,在此处传入
     */
    public static <S, D> List<D> mapList(Iterable<S> sourceList, Type<S> sourceType, Type<D> destinationType) {
        return mapper.mapAsList(sourceList, sourceType, destinationType);
    }

    /**
     * 简单复制出新对象列表到数组.
     * <p>
     * 内部实现是通过source.getComponentType() 获得源Class
     *
     * @param destination      要复制到的目标数组
     * @param source           待复制的源数据数组
     * @param destinationClass 要复制到的目标数组数据元素Class
     */
    public static <S, D> D[] mapArray(final D[] destination, final S[] source, final Class<D> destinationClass) {
        return mapper.mapAsArray(destination, source, destinationClass);
    }

    /**
     * 极致性能的复制出新类型对象到数组.
     * <p>
     * 需要预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存转换所需Type类型,在此处传入
     *
     * @param destination     要复制到的目标数组
     * @param source          待复制的源数据数组
     * @param sourceType      待复制的源数据数组实例类型
     * @param destinationType 要复制到的目标数组类型
     */
    public static <S, D> D[] mapArray(D[] destination, S[] source, Type<S> sourceType, Type<D> destinationType) {
        return mapper.mapAsArray(destination, source, sourceType, destinationType);
    }

    /**
     * 预先获取orika转换所需要的{@link Type},避免每次复制都做转换.
     */
    public static <E> Type<E> getType(final Class<E> rawType) {
        return TypeFactory.valueOf(rawType);
    }

}

 使用示例:

 通过上图 我们可以看到 已经成功转换成Vo对应的泛型

如果是对集合School进行拷贝,可以使用mapList方法  这里不再演示

注意:集合泛型不一样  但对应的字段名称 务必保持一致

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值