详见: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集合却没实现这接口的更多相关文章

  1. 集合框架——LinkedList集合源码分析

    目录 示例代码 底层代码 第1步(初始化集合) 第2步(往集合中添加一个元素) 第3步(往集合中添加第二个元素) 第4步(往集合中添加第三个元素) LinkedList添加元素流程示意图 第5步(删除 ...

  2. IT第二十一天 - Collections、ArrayList集合、LinkedList集合、Set集合、HashMap集合、集合的操作注意【修20130828】

    NIIT第二十一天 上午 集合 1. 集合Collection存储数据的形式是单个存储的,而Map存储是按照键值对来存储的,键值对:即键+值同时存储的,类似align="center&quo ...

  3. HashMap,Hashset,ArrayList以及LinkedList集合的区别,以及各自的用法

    基础内容 容器就是一种装其他各种对象的器皿.java.util包 容器:Set, List, Map ,数组.只有这四种容器. Collection(集合) 一个一个往里装,Map 一对一对往里装. ...

  4. Java 中的接口有什么作用?好处?

    接口的作用就是把使用接口的人和实现接口的人分开,实现接口的人不必要关心谁去使用,而使用接口的人也不用关心谁实现的接口,由接口将他们联系在一起. 很多JAVA初级程序员对于接口存在的意义很疑惑.不知道接 ...

  5. java接口定义和作用

    接口语法 1.接口是一种引用类型,可以等同看作类.修饰符 interface 接口名 2.接口中只能出现常量和抽象方法 3.接口其实是一个特殊的抽象类,特殊在接口是完全抽象的 4.接口中没有构造方法, ...

  6. Java 中的接口有什么作用?以及接口和其实现类的关系?

    Java 中的接口有什么作用? - Ivony的回答 - 知乎 https://www.zhihu.com/question/20111251/answer/16585393 这是一个初学者非常常见的 ...

  7. C# List.Sort与IComparer接口及Comparison委托应用于集合排序

    C#里List.Sort的用法 using System; using System.Collections.Generic; using System.Linq; using System.Text ...

  8. Rommel - C# 浅谈 接口(Interface)的作用

    鉴于网上太多太多的对C# 接口的误解,想来想去还是自己做一个完美的接口 篇章 继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基 ...

  9. C# 浅谈 接口(Interface)的作用

    继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基类无法实现的 1.接口用于描述一组类的公共方法/公共属性. 它不实现任何的方法 ...

随机推荐

  1. 将linux上的网站代码托管到gogs git服务器上进行实时同步(实战)

    一.说明 本说明只针对php,其他语言需要编译请用别的架构实现 二.实现效果 本地开发员门提交推送代码到git服务器,会立即同步更新网站服务器上代码 三.实战步骤小节 首次托管请先看   https: ...

  2. WAL streaming (max_wal_senders > 0) requires wal_level "replica" or "logical"

    初次使用pg的11版本,执行以下操作修改归wal_level设置: alter system set set wal_level='minimal'; 尝试重启pg,发现重启失败,并报错: waiti ...

  3. postgresql 中文排序

    select c_wsxx from fjfl.t_case_anyou order by convert_to(c_wsxx,'GBK') asc;

  4. echarjs—阿里历年双十一销售数据统计及预测

    阿里双十一数据统计 <!DOCTYPE html> <html> <head> <title>阿里历年双十一销售数据统计及预测</title> ...

  5. kafka与Rocketmq的区别

    淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用Mysql作为消息存储媒介,可完全水平扩容,为了进一步降低成本,我们认为存储部分可以进一步优化,2011年初,Linkin开源了Kaf ...

  6. OpenShift 4.1 基本问题探索

    因为在OpenShift 4.1环境中不建议直接登录集群主机操作,因此很多操作可能需要在外部的Client VM上完成.当然用rhel的worker node的同事也可以和原来习惯保持一致. 这里记录 ...

  7. jquery trigger使用方法

    jquery trigger使用方法比方说写了下面点击事件 采用trigger 要触发他<pre> $('.biaoqian_ula').on('click',function () { ...

  8. 07 Mybatis的多表查询1----1对多和多对1---@Results注解用法总结

    1.表与表之间的关系及其举例 表之间的关系有4种:一对多.多对一.一对一.多对多. 举例: (1)用户和订单就是一对多 一个用户可以下多个订单 (2)订单和用户就是多对一 多个订单属于同一个用户 (3 ...

  9. Windows 下删除 Docker 容器的方法

    Issue: 删除命令执行失败 如果在 CMD 命令提示符下删除容器可能失败,可切换至 PowerShell 中执行成功. unknown shorthand flag: 'a' in -a See ...

  10. AVR单片机教程——按键状态

    好久没更新了,今天开始继续,争取日更. 今天我们来讲按键.开发板的右下角有4个按键,按下会有明显的“咔嗒”声.如何检测按键是否被按下呢?首先要把按键或直接或间接地连接到单片机上.与之前使用的4个LED ...