移除集合效率高还是add高_java-集合处理数据的效率差异

先给结论,ArrayList数组结构的,插入和删除耗时长,get(index)耗时短。

LinkedList是链表结构的,插入和删除耗时短,get(index)耗时长。

常用的几种集合,ArrayList和LinkedList,看了一下这两种集合获取数据的效率。

public class TestList {

@Test

public void testLink() throws InterruptedException {

LinkedList link = new LinkedList();

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

link.add(i);

}

long time1 = System.currentTimeMillis();

//用link找坐标,花费时间大

//用link遍历Iterator数据,开销少于arrayList

for(int i :link){

link.set(i,55);

}

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

@Test

public void testArray() throws InterruptedException {

ArrayList link = new ArrayList();

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

link.add(i);

}

long time1 = System.currentTimeMillis();

for(int i :link){

link.set(i,55);

}

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

}

结果

12

4809

用Iterator迭代器,遍历LinkedList和ArrayList进行set/get 操作,很明显ArrayList的耗时要高很多。

同样的,用for循环读下标也是。

另一个例子

public class TestList {

@Test

public void testLink() throws InterruptedException {

LinkedList link = new LinkedList();

long time1 = System.currentTimeMillis();

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

link.add(i);

}

//用link找坐标,花费时间大

//用link遍历Iterator数据,开销少于arrayList

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

@Test

public void testArray() throws InterruptedException {

ArrayList link = new ArrayList();

long time1 = System.currentTimeMillis();

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

link.add(i);

}

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

}

结果

28

14

LinkedList在add时,耗时比ArrayList多一倍。

public class TestList {

@Test

public void testLink() throws InterruptedException {

LinkedList link = new LinkedList();

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

link.add(i);

}

long time1 = System.currentTimeMillis();

for(int i = 500;i<1000;i++){

link.remove(i);

}

//用link找坐标,花费时间大

//用link遍历Iterator数据,开销少于arrayList

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

@Test

public void testArray() throws InterruptedException {

ArrayList link = new ArrayList();

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

link.add(i);

}

long time1 = System.currentTimeMillis();

for(int i = 500;i<1000;i++){

link.remove(i);

}

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

}

结果

28

6

LinkedList在按照下标remove数据上,比ArrayList慢,这里和java-core上有些差异。

重新设置一下数据,让数据量较大,并且读取的数据较靠后,ArrayList的耗时就明显增加了。

public class TestList {

@Test

public void testLink() throws InterruptedException {

LinkedList link = new LinkedList();

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

link.add(i);

}

Iteratorit = link.iterator();

long time1 = System.currentTimeMillis();

for(int i = 99000;i<99599;i++){

link.remove(i);

}

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

@Test

public void testArray() throws InterruptedException {

ArrayList link = new ArrayList();

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

link.add(i);

}

long time1 = System.currentTimeMillis();

for(int i = 99000;i<99599;i++){

link.remove(i);

}

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

}

结果:

291

898

这里摘抄一段java-core的解释,P568

数组和数组列表都有一个重大的缺陷,这就是从数组的中间位置删除一个元素要付出很大的代价,其原因是数组中处于被删除元素之后的所有元素都要向数组的前端移动,在数组中间的位置上插入一个元素也是如此。

从链表中间删除一个元素时一个很轻松的操作,即需要对被删除元素附近的节点更新一下即可。

但是链表与泛型集合之间有一个重要的区别,链表是一个有序集合(ordered collection),每个对象的位置十分重要。

这里又有一个疑问,P572说LinkedList下标读取object的效率不高,并且用for循环来读取下标的效率极低。事实上我测试的时候,ArrayList的get(i)效率更低,参见下面的代码。

public class TestList {

@Test

public void testLink() throws InterruptedException {

LinkedList link = new LinkedList();

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

link.add(i);

}

long time1 = System.currentTimeMillis();

//用link找坐标,花费时间大

//用link遍历Iterator数据,开销少于arrayList

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

link.get(55);

}

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

@Test

public void testArray() throws InterruptedException {

ArrayList link = new ArrayList();

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

link.add(i);

}

long time1 = System.currentTimeMillis();

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

link.get(55);

}

long time2 = System.currentTimeMillis();

System.out.println(time2-time1);

}

}

结果就不贴了,跟第一段代码的set的效率差异差不多大。

很难懂啊。。。。

搜了一下,应该是我的代码有问题。后来发现可能是因为我有两个test,test可能执行上有差异导致的?没研究清楚,分开执行结果是正确的,放在一起执行就是有问题。。。

参考https://www.cnblogs.com/skywang12345/p/3308900.html

修改了一下测试代码

package enums;

import org.junit.Test;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.LinkedList;

import java.util.List;

/**

* Created by user on 2019/7/2.

*/

public class TestList {

@Test

public void testLink() throws InterruptedException {

LinkedList linklist= new LinkedList<>();

ArrayListarrayList = new ArrayList<>();

addList(linklist);

addList(arrayList);

getList(linklist);

getList(arrayList);

}

public void getList(List list){

long startTime = System.currentTimeMillis();

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

list.get(i);

}

long endTime = System.currentTimeMillis();

System.out.println(endTime-startTime);

}

public void addList(List list){

long startTime = System.currentTimeMillis();

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

list.add(i);

}

long endTime = System.currentTimeMillis();

System.out.println(endTime-startTime);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值