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 VS Live Share 实时编码分享(和你的小伙伴一起写代码吧)
Visual Studio Live Share能干啥? 分享任何语言,任何应用程序 无论您正在构建什么类型的应用程序,您正在编写什么语言,或者您的操作系统如何:在您需要协作时,Live Share会 ...
- android 连接蓝牙打印机 BluetoothAdapter
android 连接蓝牙打印机 BluetoothAdapter 源码下载地址:https://github.com/yylxy/BluetoothText.git public class Prin ...
- Python之pandas读取mysql中文乱码问题
# -*- coding: utf-8 -*- # author:baoshan import pandas as pd import pymysql config = { "host&qu ...
- Qt编写气体安全管理系统29-跨平台
一.前言 Qt的跨平台特性是非常厉害的,本来作为C++来说,跨平台的特性比JAVA还要好,只不过学习难度更大,所以大家更理解的跨平台是JAVA,Qt的跨平台特性是我见过的所有开发环境和语言中最厉害的, ...
- laravel composer 使用阿里云镜像
使用composer安装错误提示: 即: [Composer\Downloader\TransportException] The "https://packagist.laravel-ch ...
- 【linux基础】ubuntu实现双屏显示
前言 之前博主没有使用NVIDIA时候已经可以实现双屏显示(拼接类型),但是,安装NVIDIA驱动使用CUDA之后这个功能就消失了,需要重新配置. 实现方式 1. 使用Intel集成显卡时实现双屏拼接 ...
- [LeetCode] 140. Word Break II 单词拆分II
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add space ...
- iptables 深度详解
iptables 是 Linux 中比较底层的网络服务,它控制了 Linux 系统中的网络操作,在 CentOS 中的 firewalld 和 Ubuntu 中的 ufw 都是在 iptables 之 ...
- Qt deletelater函数分析(1)
生活的全部意义在于无穷地探索尚未知道的东西,在于不断地增加更多的知识.--左拉 该函数是QObject类的函数: ---- ...
- 使用Kali MDK3无线攻击
mdk3 <接口> <测试_模块> [测试选项] 例:mdk3 --wlan0mon b (通过mdk3 使用网卡接口调用b类测试模块发起攻击)请注意该mdk3软件在使用时必须 ...