ArrayList集合实现RandomAccess接口有何作用?为何LinkedList集合却没实现这接口
详见:https://blog.csdn.net/weixin_39148512/article/details/79234817
众所周知,在List集合中,我们经常会用到ArrayList以及LinkedList集合,但是通过查看源码,就会发现ArrayList实现RandomAccess接口,但是RandomAccess接口里面是空的!Linked并没有实现RandomAccess接口。
这是为什么呢?
-----------------------------------------------------------------------------------------------------
这是ArrayList实现RandomAccess接口的源码

------------------------------------------------------------------------------------------------------
这是LinkedList的源码,并没实现RandomAccess接口

------------------------------------------------------------------------------------------------------
这是RandomAccess接口的源码

原来RandomAccess接口是一个标志接口(Marker),然而实现这个接口有什么作用呢?
解答:只要List集合实现这个接口,就能支持快速随机访问,然而又有人问,快速随机访问是什么东西?有什么作用?
通过查看Collections类中的binarySearch()方法,源码如下:

由此可以看出,判断list是否实现RandomAccess接口来实行indexedBinarySerach(list,key)或iteratorBinarySerach(list,key)方法。ps(instanceof其作用是用来判断某对象是否为某个类或接口类型)
那么,又有人疑问,执行这两个方法有什么不同?
查看下indexedBinarySerach(list,key)方法源码:

-------------------------------------------------------------------------------------------------------------
查看下iteratorBinarySerach(list,key)方法源码:

通过查看源代码,发现实现RandomAccess接口的List集合采用一般的for循环遍历,而未实现这接口则采用迭代器。
接下来,我们将进行下测试ArrayList以及LinkedList采用这两种方法各自的性能是如何!

for循环遍历ArrayList

-------------------------------------------------------------------------------------------------------------
iterator迭代器遍历ArrayList

for循环遍历LinkedList

-------------------------------------------------------------------------------------------------------------
iterator迭代器遍历LinkedList

-------------------------------------------------------------------------------------------------------------
运行结果:

从上面数据可以看出,ArrayList用for循环遍历比iterator迭代器遍历快,LinkedList用iterator迭代器遍历比for循环遍历快,
所以说,当我们在做项目时,应该考虑到List集合的不同子类采用不同的遍历方式,能够提高性能!
然而有人发出疑问了,那怎么判断出接收的List子类是ArrayList还是LinkedList呢?
这时就需要用instanceof来判断List集合子类是否实现RandomAccess接口!

main方法:

运行结果:

总结:RandomAccess接口这个空架子的存在,是为了能够更好地判断集合是否ArrayList或者LinkedList,从而能够更好选择更优的遍历方式,提高性能!
个人测试类
package com.my.test.base; import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.RandomAccess; public class TestRandomAccess {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
LinkedList<String> link = new LinkedList<>();
for (int i = 0; i < 5000; i++) {
list.add(i + "");
link.add(i + "");
}
accessList(list);
accessList(link);
accessListByFor(list);
accessListByIterator(list);
accessListByFor(link);
accessListByIterator(link);
} public static long accessList(List list) {
if (list != null) {
if (list instanceof RandomAccess) {
System.out.println("有实现RandomAccess接口的用for遍历");
long start = System.nanoTime();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
long end = System.nanoTime();
System.out.println("耗时: " + (end - start)); return end - start;
} else {
System.out.println("没有实现RandomAccess接口的用Iterator遍历");
long start = System.nanoTime();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
iterator.next();
} long end = System.nanoTime();
System.out.println("耗时: " + (end - start)); return end - start; } } else {
throw new RuntimeException("List is null");
}
} public static long accessListByIterator(List list) { long start = System.nanoTime();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
iterator.next();
}
long end = System.nanoTime();
System.out.println(list.getClass().getName() + " 用Iterator遍历耗时:" + (end - start)); return end - start;
} public static long accessListByFor(List list) { long start = System.nanoTime();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
long end = System.nanoTime();
System.out.println(list.getClass().getName() + " for遍历耗时:" + (end - start)); return end - start;
}
}
测试结果
有实现RandomAccess接口的用for遍历
耗时: 1286864
没有实现RandomAccess接口的用Iterator遍历
耗时: 2352547
java.util.ArrayList for遍历耗时:552744
java.util.ArrayList 用Iterator遍历耗时:1962713
java.util.LinkedList for遍历耗时:72314258
java.util.LinkedList 用Iterator遍历耗时:675028
ArrayList集合实现RandomAccess接口有何作用?为何LinkedList集合却没实现这接口的更多相关文章
- 集合框架——LinkedList集合源码分析
目录 示例代码 底层代码 第1步(初始化集合) 第2步(往集合中添加一个元素) 第3步(往集合中添加第二个元素) 第4步(往集合中添加第三个元素) LinkedList添加元素流程示意图 第5步(删除 ...
- IT第二十一天 - Collections、ArrayList集合、LinkedList集合、Set集合、HashMap集合、集合的操作注意【修20130828】
NIIT第二十一天 上午 集合 1. 集合Collection存储数据的形式是单个存储的,而Map存储是按照键值对来存储的,键值对:即键+值同时存储的,类似align="center&quo ...
- HashMap,Hashset,ArrayList以及LinkedList集合的区别,以及各自的用法
基础内容 容器就是一种装其他各种对象的器皿.java.util包 容器:Set, List, Map ,数组.只有这四种容器. Collection(集合) 一个一个往里装,Map 一对一对往里装. ...
- Java 中的接口有什么作用?好处?
接口的作用就是把使用接口的人和实现接口的人分开,实现接口的人不必要关心谁去使用,而使用接口的人也不用关心谁实现的接口,由接口将他们联系在一起. 很多JAVA初级程序员对于接口存在的意义很疑惑.不知道接 ...
- java接口定义和作用
接口语法 1.接口是一种引用类型,可以等同看作类.修饰符 interface 接口名 2.接口中只能出现常量和抽象方法 3.接口其实是一个特殊的抽象类,特殊在接口是完全抽象的 4.接口中没有构造方法, ...
- Java 中的接口有什么作用?以及接口和其实现类的关系?
Java 中的接口有什么作用? - Ivony的回答 - 知乎 https://www.zhihu.com/question/20111251/answer/16585393 这是一个初学者非常常见的 ...
- C# List.Sort与IComparer接口及Comparison委托应用于集合排序
C#里List.Sort的用法 using System; using System.Collections.Generic; using System.Linq; using System.Text ...
- Rommel - C# 浅谈 接口(Interface)的作用
鉴于网上太多太多的对C# 接口的误解,想来想去还是自己做一个完美的接口 篇章 继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基 ...
- C# 浅谈 接口(Interface)的作用
继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基类无法实现的 1.接口用于描述一组类的公共方法/公共属性. 它不实现任何的方法 ...
随机推荐
- [转]vscode 插件推荐 - 献给所有前端工程师(2019.8.7更新)
原文地址:https://segmentfault.com/a/1190000006697219 VScode现在已经越来越完善.性能远超Atom和webstorm,你有什么理由不用它?在这里,我会给 ...
- vue---splitpane分割
使用splitpane可以对窗口进行拆分,这个splitpane组件还是比较好用的, 首先安装: npm install vue-splitpane 引入使用: import splitPane fr ...
- 必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱
必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱 十三.小心使用智能指针. 在前面几节已经很详细了介绍了智能指针适用方式.看起来,似乎智能指针很强大,能够很方便很安全的管理 ...
- EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载
为了让页面更快完成加载, 第一时间呈现给客户端, 也为了帮助客户端节省流量资源, 我们可以开启 vue-router 提供的按需加载功能, 让客户端打开页面时, 只自动加载必要的资源文件, 当客户端操 ...
- iptables的statistic模块配置rr
网上搜的是这样的 : iptables -A PREROUTING -t nat -d 172.17.64.8 -m statistic --mode nth --every 2 --packet 0 ...
- js 二叉树算法
//生成二叉树 function binarySearchTree() { let Node = function(key) { this.key = key; this.left = null; t ...
- [LeetCode] 243. Shortest Word Distance 最短单词距离
Given a list of words and two words word1 and word2, return the shortest distance between these two ...
- Python虚拟环境Virtualen简单使用
安装pip 使用脚本安装和升级pip 要安装或升级pip,需要下载 get-pip.py. 地址:https://bootstrap.pypa.io/get-pip.py 然后运行以下命令 (需要管理 ...
- Javaspring+mybit+maven中实现定时任务
背景:在Javaspring中,定时的启动某一个任务时,使用@Scheduled来实现 Javaspring工程创建好之后,直接创建下面的class文件即可.具体的用法可参照 https://www. ...
- java并发-ReentrantLock的lock和lockInterruptibly的区别
ReentrantLock的加锁方法Lock()提供了无条件地轮询获取锁的方式,lockInterruptibly()提供了可中断的锁获取方式.这两个方法的区别在哪里呢?通过分析源码可以知道lock方 ...