Java中ArrayList和LinkedList之间的区别_动力节点Java学院整理
作者:lijiao 发布时间:2023-03-30 18:16:29
一、ArrayList
ArrayList是一个可以处理变长数组的类型,这里不局限于“数”组,ArrayList是一个泛型类,可以存放任意类型的对象。顾名思义,ArrayList是一个数组列表,因此其内部是使用一个数组来存放对象的,因为Object是一切类型的父类,因而ArrayList内部是有一个Object类型的数组类存放对象。ArrayList类常用的方法有add()、clear()、get()、indexOf()、remove()、sort()、toArray()、toString()等等,同时ArrayList内部有一个私有类实现Iterator接口,因此可以使用iterator()方法得到ArrayList的迭代器,同时,还有一个私有类实现了ListIterator接口,因此ArrayList也可以调用listIterator()方法得到ListIterator迭代器。
由于ArrayList是依靠数组来存放对象的,只不过封装起来了而已,因此其一些查找方法的效率都是O(n),跟普通的数组效率差不多,只不过这个ArrayList是一个可变”数组“,并且可以存放一切指定的对象。
另外,由于ArrayList的所有方法都是默认在单一线程下进行的,因此ArrayList不具有线程安全性。若想在多线程下使用,应该使用Colletions类中的静态方法synchronizedList()对ArrayList进行调用即可。
二、LinkedList
LinkedList可以看做为一个双向链表,所有的操作都可以认为是一个双向链表的操作,因为它实现了Deque接口和List接口。同样,LinkedList也是线程不安全的,如果在并发环境下使用它,同样用Colletions类中的静态方法synchronizedList()对LinkedList进行调用即可。
在LinkedList的内部实现中,并不是用普通的数组来存放数据的,而是使用结点<Node>来存放数据的,有一个指向链表头的结点first和一个指向链表尾的结点last。不同于ArrayList只能在数组末尾添加数据,LinkList可以很方便在链表头或者链表尾插入数据,或者在指定结点前后插入数据,还提供了取走链表头或链表尾的结点,或取走中间某个结点,还可以查询某个结点是否存在。add()方法默认在链表尾部插入数据。总之,LinkedList提供了大量方便的操作方法,并且它的插入或增加等方法的效率明显高于ArrayList类型,但是查询的效率要低一点,因为它是一个双向链表。
因此,LinkedList与ArrayList最大的区别是LinkedList更加灵活,并且部分方法的效率比ArrayList对应方法的效率要高很多,对于数据频繁出入的情况下,并且要求操作要足够灵活,建议使用LinkedList;对于数组变动不大,主要是用来查询的情况下,可以使用ArrayList。
import java.util.* ;
public class ListDemo01{
public static void main(String args[]){
List<Integer> li = new LinkedList<Integer>() ;
long startTime = System.currentTimeMillis() ;
for(int i=0;i<1000000;i++){
li.add(0,i) ; //print : 803
//li.add(i) ; //print : 790
}
long endTime = System.currentTimeMillis() ;
System.out.println(endTime-startTime) ;
}
}
下面的代码得不出结果速度太慢
import java.util.* ;
public class ListDemo01{
public static void main(String args[]){
List<Integer> li = new LinkedList<Integer>() ;
for(int i=0;i<1000000;i++){
li.add(0,i) ; //print : 803
//li.add(i) ; //print : 790
}
long startTime = System.currentTimeMillis() ;
for(int i=0;i<1000000;i++){
li.get(i) ;
}
long endTime = System.currentTimeMillis() ;
System.out.println(endTime-startTime) ;
}
}
下面化成ArrayList速度就超快
import java.util.* ;
public class ListDemo01{
public static void main(String args[]){
List<Integer> li = new ArrayList<Integer>() ;
for(int i=0;i<1000000;i++){
li.add(i) ;
}
long startTime = System.currentTimeMillis() ;
for(int i=0;i<1000000;i++){
li.get(i) ; //print : 15
}
long endTime = System.currentTimeMillis() ;
System.out.println(endTime-startTime) ;
}
}
remove方法对LinkedList类的使用
a.利用iterator类
import java.util.* ;
public class ListDemo01{
public static void main(String args[]){
List<Integer> li = new LinkedList<Integer>() ;
for(int i=0;i<1000000;i++){
li.add(i) ;
}
long startTime = System.currentTimeMillis() ;
Iterator<Integer> it = li.iterator() ;
while(it.hasNext()){
if(it.next()%2==0){
it.remove() ;
}
}
long endTime = System.currentTimeMillis() ;
System.out.println(endTime-startTime) ;
}
}
b.不利用iterator的话则则需要调用get方法。则效率很低
import java.util.* ;
public class ListDemo01{
public static void main(String args[]){
List<Integer> li = new LinkedList<Integer>() ;
for(int i=0;i<1000000;i++){
li.add(i) ;
}
long startTime = System.currentTimeMillis() ;
for(int i=0;i<10000;i++){
if(li.get(i)%2==0){
li.remove(i) ;
}
}
long endTime = System.currentTimeMillis() ;
System.out.println(endTime-startTime) ;
}
}


猜你喜欢
- 此问题背景产生于近期需要上线的一个功能的埋点;主要表现就是在应用启动之后的一段时间内,内存使用一直呈现递增趋势。下图为场景复线后,本地通过
- StreamAPI中的stream不能被重复消费,一旦它被使用,stream就被关闭了,别的地方再消费它就会抛IllegalStateExc
- Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindServ
- URL(Uniform Resource Locator)是统一资源 * ,它是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,
- 前言:众所周知,大家在很多项目中都会使用到图表,具体表现形式为饼图、折线图、柱状图等,但是网上有很多图表架包都是需要收费的,而Google的
- 1. JAVA 内存模型 (JMM)JMM是用来干嘛的?:《Java虚拟机规范》中曾试图定义一种“Java内存模型&am
- 本篇文章主要介绍了Android 三方库混淆规则,分享给大家,具体如下:基本指令-optimizationpasses 5-dontusem
- 首先看下面这一段代码:interface a{ void b();}interface a1 extends a{
- 1. 背景Java Persistence with Hibernate 在12.2.1小节使用如下例子描述 n+1查询问题:List<
- 使用函数detectAndCompute()检测关键点并计算描述符函数detectAndCompute()参数说明:void detectA
- 前言大家对AOP应该都不陌生, 就算没有用过也肯定听说过,切面编程一直是一个热点的话题,AOP即Aspect Oriented Progra
- 生成TAGlogt+Tab键:private static final String TAG = "Extract";生
- 如果 d:\upload\file\ 文件夹不存在,会报错String strPath = "d:\\upload\\file\\
- maven 文件打包,输入 :package -Dmaven.test.skip=true 进行打包, 一般生成的jar 文件 名称是项目名
- 大家是不是平常都有好多文件需要定期备份?如歌曲、视频、文档,代码文件等等,如果经常增加删除修改文件,就需要定期备份,最早之前文件都不大的时候
- 命令模式的介绍命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象每一个命令都是一个操作:请求的一方发出
- SpringAop @Aspect织入不生效,不执行前置增强织入@Before想写一个AOP,主要有2个用意第一个用意是做后端的防表单重复提
- RestTemplate未设置超时时间,导致RabbitMQ队列大量堆积,消费者假死,不进行消费,类似线程堵塞。排查:从日志排查问题,在从进
- 方法一:使用多个controller的共同拥有的父类,即精确到两个controller的上一级@Beanpublic Docket crea
- 数组的用处是什么呢?——当你需要将30个数进行大小排列的时候,用数组这样的数据结构存储是个很好的选择,当你是一个班的班主任的时候,每次要记录