基于CGLIB高性能LIST集合对象复制工具类

1.前言

      java开发少不了RO、DTO、VO之类的对象复制,大部分都是基于各类框架提供的方法,比如

CGLIB 
dozer
orika
Apache BeanUtils
Apache PropertyUtil
Spring BeanUtils

之类的,性能上最强的目前不容置疑的是CGLIB,和手动set、get速度基本一致,甩其他工具几条街,但可能是我用的不熟悉,始终没有找到可以复制list集合对象的方法。

所以在这里我自己手动扩展了下,代码不算优雅,但性能上比其他工具类强上很多。

2.CGLIB

    private static final ConcurrentHashMap mapCaches = new ConcurrentHashMap<>();
    
    /**
     *
     * @param source 原数据,list集合
     * @param target 接收复制的数据实体类属性,会自动转换成list集合
     * @param sourceKey 原数据的实体类属性,为了防止空数据获取该属性报错
     * @param 
     * @param 
     * @return
     */
    public static  List listCopyMapper(List source, T target, O sourceKey) {
        String baseKey = generateKey(sourceKey.getClass(), target.getClass());
        BeanCopier copier;
        if (!mapCaches.containsKey(baseKey)) {
            copier = BeanCopier.create(sourceKey.getClass(), target.getClass(), false);
            mapCaches.put(baseKey, copier);
        } else {
            copier = mapCaches.get(baseKey);
        }
        List targets = new ArrayList<>();
        try {
            source.stream().forEach(
                    bean -> {
                        T instance = null;
                        try {
                            instance = (T) target.getClass().getDeclaredConstructor().newInstance();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (NoSuchMethodException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        }
                        copier.copy(bean, instance, null);
                        targets.add(instance);
                    }
            );
        } catch (Exception e) {
            log.error("list bean复制失败" + e.getMessage());
        }
        return targets;
    }

开启服务器一条数据简单测试了下,一次替换大概在6万纳秒左右,有时候会波动下,但大概不变。

同样的替换成spring的BeanUtils,大概在13万纳秒左右,偶尔波动到20多万纳秒。

偶然发现了orika有个直接复制list的,工具类大概长这样

import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;

import java.util.List;

public class MapperUtils {

	static {
		mapperFactory = new DefaultMapperFactory.Builder().build();
	}

	private static MapperFactory mapperFactory;

	public static  List mapAsList(Iterable source, Class destinationClass) {
		return mapperFactory.getMapperFacade().mapAsList(source, destinationClass);
	}
}

引入jar


            
                ma.glasnost.orika
                orika-core
                1.5.2
            

这个封装的不错,但实际性能就差强人意了,基本18、20w纳秒出头,有时候能蹦到30w纳秒,这还是在静态代码块提前创建mapperFactory的情况下,如果在使用的时候创建,那速度基本没眼看了。

大量数据可能性能上会有偏差,但我没空测试了,仅供参考。

你可能感兴趣的:(java)