当前位置: 首页>移动开发>正文

java 6种拷贝集合方式及其性能差异对比


文章目录

  • ArrayList 构造方法拷贝
  • 运行1000次耗时 1ms
  • for循环拷贝
  • 运行1000次耗时 14ms
  • Stream流 collect实现拷贝
  • 运行1000次耗时 54ms
  • Stream流+spring的BeanUtils实现拷贝
  • 运行1000次耗时 2468 ms
  • Hutool工具实现拷贝
  • Hutool 5.7.13版本运行1000次耗时 64674 ms
  • Hutool 5.8.24版本运行1000次耗时 15874 ms
  • JSON序列化
  • 运行1000次 耗时 3387 ms
  • 结论


测试背景
在项目中很多地方需要拷贝对象集合、A类型对象的集合转换到B类型这种操作,但是这种操作的完成是有各种写法的,每种写法的性能可能不一样,因此对比一下各个写法的性能差异,选择最优解。
对一个有1000个对象的List复制1000次
ActivityCouponVO 对象有35个字段,各类型都有

/**
     * 集合大小
     */
    private int len = 1000;
    /**
     * 循环次数
     */
    private int loop = 1000;
	List<ActivityCouponVO> getList(int len){
     // ... 生成一千个这个对象的集合,且每个字段赋值了
}

测试方法完整代码示范如下,后续各种方式的代码只写一次复制的代码示意,不写外层循环和耗时打印这些了

java 6种拷贝集合方式及其性能差异对比,java 6种拷贝集合方式及其性能差异对比_深拷贝,第1张

ArrayList 构造方法拷贝

底层使用了Arrays.copyOf()方法,这个方法底层又用了System.arraycopy方法,这个方法是native方法,使用本地实现,(一般为c++),直接操作内存复制,效率高
注意:new ArrayList<>(list)、Arrays.copyOf()、System.arraycopy这三个都是浅拷贝!!!

List<ActivityCouponVO> list = getList(len);
ArrayList<ActivityCouponVO> activityCouponVOS = new ArrayList<>(list);

运行1000次耗时 1ms

for循环拷贝

这个直接add 对象 也是浅拷贝,拷贝的是对象的内存地址
如果要深拷贝则循环的时候每次new一个新的对象并复制属性值

List<ActivityCouponVO> list = getList(len);
			List<ActivityCouponVO> collect = new ArrayList<>(len);
            for (ActivityCouponVO activityCouponVO : list) {
                collect.add(activityCouponVO);
            }

运行1000次耗时 14ms

Stream流 collect实现拷贝

浅拷贝

List<ActivityCouponVO> list = getList(len);
List<ActivityCouponVO> collect = list.stream().collect(Collectors.toList());

运行1000次耗时 54ms

Stream流+spring的BeanUtils实现拷贝

这种拷贝方式是第一层属性深拷贝,嵌套的对象是浅拷贝

List<ActivityCouponVO> list = getList(len);
List<ActivityCouponVO> activityCouponVOS = list.stream().map(o -> {
                ActivityCouponVO activityCouponVO = new ActivityCouponVO();
                BeanUtils.copyProperties(o, activityCouponVO);
                return activityCouponVO;
            }).collect(Collectors.toList());

运行1000次耗时 2468 ms

Hutool工具实现拷贝

这种拷贝方式是第一层属性深拷贝,嵌套的对象是浅拷贝

List<ActivityCouponVO> list = getList(len);
List<ActivityCouponVO> activityCouponVOS = BeanUtil.copyToList(list, ActivityCouponVO.class);

Hutool 5.7.13版本运行1000次耗时 64674 ms

(看了下源码是因为加锁了)

Hutool 5.8.24版本运行1000次耗时 15874 ms

(新版本里没有加锁了,而且还做了优化,例如properties缓存)

JSON序列化

完全深拷贝

JSONObject.parseArray(JSONObject.toJSONString(list), ActivityCouponVO.class);

运行1000次 耗时 3387 ms

结论

不需要深拷贝时建议使用
Arrays.copyOf()
System.arraycopy
这种本地实现的拷贝数组方式
深拷贝时可以使用for循环、stream流、BeanUtils工具等方式实现,但是要注意使用工具的时候看看工具的源码实现,有可能里面有锁,然后有性能的坑~



https://www.xamrdz.com/mobile/4gw1930623.html

相关文章: