java矩阵addall_为什么Collections.addAll()比arrays.addAll()性能好?

本文探讨了在Java中Collections.addAll()与arrays.addAll()的性能差异,并通过测试发现Collections.addAll()性能更优。文章解释了两者在实现上的区别,arrays.addAll()额外创建了集合并进行了数组长度校验,这导致其效率较低。建议在开发中优先选择Collections.addAll()以提升性能。
摘要由CSDN通过智能技术生成

1. Collections.addAll()比arrays.addAll()更快吗?

在《Java核心编程》这本书中,“持有对象”这一章有个地方讲到:

Collections.addAll()比arrays.addAll()方法快得多!

我们知道,Collections是一个工具类,它提供了一组操作集合类的静态方法,包括排序、交换元素、拷贝、最大值、最小值等,使用起来非常方便。addAll()方法就是其中之一,它用来将一组元素添到一个集合中:

List arrays = new ArrayList<>();

Collections.addAll(arrays, "hello", "world");

而arrays.addAll()方法,是List对象的一个方法,它实现的功能与Collections.addAll()类似,也是将一组元素添加到数组中:

List arrays = new ArrayList<>();

arrays.addAll(Arrays.asList("hello", "world"));

2. 是不是真的更快?

尽信书不如无书,书上虽然是这样说的,那是不是真的Collections.addAll()比arrays.addAll()性能好很多呢?我们不妨来测试一下:

public class Test {

public static void main(String[] args) {

//循环次数

int count = 100000000;

System.out.println("Collections.addAll()耗时:" + collectionsTest(count) + "ms");

System.out.println("arrays.addAll()耗时:" + arraysTest(count) + "ms");

}

public static long collectionsTest(int count) {

long startTime = System.currentTimeMillis();

for (int i = 0; i < count; i++) {

List arrays = new ArrayList<>();

Collections.addAll(arrays, "hello", "world");

}

return System.currentTimeMillis() - startTime;

}

public static long arraysTest(int count) {

long startTime = System.currentTimeMillis();

for (int i = 0; i < count; i++) {

List arrays = new ArrayList<>();

arrays.addAll(Arrays.asList("hello", "world"));

}

return System.currentTimeMillis() - startTime;

}

}

我们使用这两个方法,向其中添加元素,分别循环一个小目标,得出耗时对比:

arrays.addAll()耗时:3324ms

Collections.addAll()耗时:2034ms

可以看到,这两个方法的耗时差距还是很大的,arrays.addAll()的耗时大概是Collections.addAll()的1.6倍左右。看来Bruce Eckel没有骗我,他是个诚实的人,说的确实对。

3. 为什么它这么快?

好了,是不是的问题已经解决了,我们已经知道,Collections.addAll()确实比arrays.addAll()方法快很多,可是:

Why?

让我们回过头来再看一眼刚才的代码,首先是Collections.addAll():

List arrays = new ArrayList<>();

Collections.addAll(arrays, "hello", "world");

public static boolean addAll(Collection super T> c, T... elements) {

boolean result = false;

for (T element : elements)

result |= c.add(element);

return result;

}

这两行代码很简单,就做了两件事情:

创建arrays

调用addAll()

使用数组迭代器,将元素添加到arrays中

然后是arrays.addAll():

List arrays = new ArrayList<>();

arrays.addAll(Arrays.asList("hello", "world"));

public boolean addAll(Collection extends E> c) {

Object[] a = c.toArray();

int numNew = a.length;

ensureCapacityInternal(size + numNew); // Increments modCount

System.arraycopy(a, 0, elementData, size, numNew);

size += numNew;

return numNew != 0;

}

它做了什么呢?可以看到:

创建arrays

使用Arrays.asList()新创建了一个集合

调用addAll()

使用c.toArray()方法复制入参到a中。(耗时较长)

使用ensureCapacityInternal()校验是否溢出

使用System.arraycopy()拷贝a中新传入的元素到数组容器elementData中

综上所述,可以得出,Collections.addAll()和arrays.addAll()主要有两种差别:

arrays.addAll()方法会在调用前使用Arrays.asList()多创建一个集合

在两个addAll()方法内部,arrays.addAll()会比Collections.addAll()多一些集合创建,数组长度校验的操作。

因此,大家在开发过程中,还是尽量使用Collections.addAll(),可以获得更好的性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值