关于接口 RandomAccess
今天看到java.util.Collections这个工具类中的
public static <T> void fill(List<? super T> list, T obj) {
int size = list.size();
if (size < FILL_THRESHOLD || list instanceof RandomAccess) { // 这一行
for (int i=0; i<size; i++)
list.set(i, obj);
} else {
ListIterator<? super T> itr = list.listIterator();
for (int i=0; i<size; i++) {
itr.next();
itr.set(obj);
}
}
}
上面代码中标识的一行, FILL_THRESHOLD 是25,就是说,如果要填充的目标List范围不是很大,那么就直接用上面的方式效率比较高,同时注意到 list instanceof RamdomAccess 这个代码,顺便翻到里面去瞅了一眼,RamdomAccess 接口是一个空接口,空接口的作用一般起到一个标识作用,比如:Serializable 接口。
RaomdomAccess接口里面的文档说明大致意思:给可以提供随机访问的List实现去标识一下,这样使用这个List的程序在遍历这种类型的List的时候可以有更高效率。仅此而已。
所以,我们在遍历List之前,可以用 if( list instanceof RamdomAccess ) 来标识一下,选择用哪种遍历方式。
测试代码:
package com.zslin.list.demo; import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.RandomAccess; //JDK中说的很清楚,在对List特别是Huge size的List的遍历算法中,
// 要尽量来判断是属于RandomAccess(如ArrayList)还是Sequence List (如LinkedList),
// 因为适合RandomAccess List的遍历算法,用在Sequence List上就差别很大,常用的作法就是:
// 要作一个判断:
// if (list instance of RandomAccess) {
// for(int m = 0; m < list.size(); m++){}
// }else{
// Iterator iter = list.iterator();
// while(iter.hasNext()){}
// } /**
*
* @author WQ<br>
* @version 创建时间:2017年6月18日 下午6:01:14<br>
*/
public class TestRandomAccess {
// 初始化列表 public static void initList(List list, int n) {
for (int i = 0; i < n; i++) {
list.add(i);
}
} // 使用循环进行对列表的迭代 public static void traverseWithLoop(List list) {
long starttime = 0;
long endtime = 0;
starttime = System.currentTimeMillis();
for (int count = 0; count <= 1000; count++) {
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
}
endtime = System.currentTimeMillis();
System.out.println("使用loop迭代一共花了" + (endtime - starttime) + "ms时间"); } // 使用迭代器对列表进行迭代 public static void traverseWithIterator(List list) {
long starttime = 0;
long endtime = 0;
starttime = System.currentTimeMillis();
for (int count = 0; count <= 1000; count++) {
for (Iterator itr = list.iterator(); itr.hasNext();) {
itr.next();
}
}
endtime = System.currentTimeMillis();
System.out.println("使用Iterator迭代一共花了" + (endtime - starttime) + "ms时间");
} public static void traverse(List list) { long starttime = 0;
long endtime = 0;
if (list instanceof RandomAccess) {
System.out.println("该list实现了RandomAccess接口");
starttime = System.currentTimeMillis();
for (int count = 0; count <= 1000; count++) {
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
}
endtime = System.currentTimeMillis();
System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");
} else {
System.out.println("该list未实现RandomAccess接口");
starttime = System.currentTimeMillis();
for (int count = 0; count <= 1000; count++) {
for (Iterator itr = list.iterator(); itr.hasNext();) {
itr.next();
}
}
endtime = System.currentTimeMillis();
System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");
}
} public static void main(String[] args) {
ArrayList arraylist = new ArrayList();
LinkedList linkedlist = new LinkedList();
initList(arraylist, 1000);
initList(linkedlist, 1000);
traverse(arraylist);
traverse(linkedlist);
traverseWithIterator(arraylist);
traverseWithLoop(arraylist);
traverseWithIterator(linkedlist);
traverseWithLoop(linkedlist);
}
}
运行结果如下:
该list实现了RandomAccess接口
迭代一共花了9ms时间
该list未实现RandomAccess接口
迭代一共花了10ms时间
使用Iterator迭代一共花了12ms时间
使用loop迭代一共花了7ms时间
使用Iterator迭代一共花了14ms时间
使用loop迭代一共花了396ms时间
以上。
关于接口 RandomAccess的更多相关文章
- OpenJDK源码研究笔记(三)-RandomAccess等标记接口的作用
标识接口是没有任何方法和属性的接口. 它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情. 下面来看一个标记接口RandomAccess. public interface Rando ...
- 难倒你了吧!ArrayList 为啥要实现 RandomAccess 接口?
作者:蔡先森_caiyq https://www.jianshu.com/p/3e2a9e4c9e01 在我们的开发中,List接口是最常见不过,而且我们几乎每天都在用ArrayList或者Linke ...
- Java 容器 接口
Java 中容器框架的内容可以分为三层: 接口(模型), 模板和具体实现. 在开发中使用容器正常的流程是,首先根据需求确定使用何种容器模型,然后选择一个符合性能要求的容器实现类或者自己实现一个容器类. ...
- Java容器解析系列(3) List AbstractList ListIterator RandomAccess fail-fast机制 详解
做为数据结构学习的常规,肯定是先学习线性表,也就是Java中的List,开始 Java中List相关的类关系图如下: 此篇作为对Java中相关类的开篇.从上图中可以看出,List和AbstractLi ...
- ArrayList 浅析示例
package com.smbea.demo; import java.util.ArrayList; import java.util.Iterator; import java.util.List ...
- java2集合框架的一些个人分析和理解
Java2中的集合框架是广为人知的,本文打算从几个方面来说说自己对这个框架的理解. 下图是java.util.Collection的类图(基本完整,有些接口如集合类均实现的Cloneable.Seri ...
- Java 核心技术-集合-集合框架
说在前面的话: 关于Core Java 集合方面的博文网上已经写烂了,为啥我还要写呢? 答:他们写的都很好,我也学到不少东西,如果把我当做一个系统的话,学习别人.看书.读源码是输入,但是往往形不成一个 ...
- Java集合类操作优化总结
清单 1.集合类之间关系 Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashMap└WeakHas ...
- Java集合类操作优化经验总结
本文首先针对 Java 集合接口进行了一些介绍,并对这些接口的实现类进行详细描述,包括 LinkedList.ArrayList.Vector.Stack.Hashtable.HashMap.Weak ...
随机推荐
- 【BZOJ2832&&3874】宅男小C [模拟退火][贪心]
宅男小C Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 众所周知,小C是个宅男,所以他的每 ...
- bzoj2683/4066 简单题
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2683 http://www.lydsy.com/JudgeOnline/problem.ph ...
- [bzoj2186][Sdoi2008]沙拉公主的困惑——数论
题目大意 求 \[\sum_{i = 1}^{N!} [gcd(i, M!) = 1]\] 题解 显然,题目就是求 \[N!(1-\frac{1}{p_1})(1-\frac{1}{p_2})...\ ...
- CentOS 7 主机加固手册-上
TIPs: 世界上有一撮人专门研究主机安全加固基线,有兴趣的读者可以到 http://benchmarks.cisecurity.org/ 获取更加详细专业的主机安全基线配置文档.或者到 https: ...
- cygwin与vim配置
参考 http://www.jeepshoe.org/810958442.htm cygwin安装包管理器 通过终端安装apt-cyg之前选要安装以下软件包wget tar gawk bzip2 ap ...
- easyui 在子tabs中打开新tabs(关于easyUI在子页面增加显示tabs的一个问题)
现在说的是在子页面点个按钮也能触发增加子页面的情况. 情景是,在父页面上有个div如: <div class="easyui-tabs" id="main" ...
- Xcode升级到7之后 发现速度超级慢
Xcode升级到7之后 发现速度超级慢 转自:http://www.jianshu.com/p/608803eb1e12 解决方法,慢google了一下是由于插件造成饿,于是乎将Alcatraz安装的 ...
- django学习随笔:ManagementUtility
ManagementUtility类,位于django.core.management目录下的__init__.py文件. 这个类,在其init中: def __init__(self, argv=N ...
- MATLAB中的符号运算
1. syms命令 可以替换sym和symfun,另外可以定义符号变量的类型,如 syms x positive; 限定x为正数. 若要取消这个限定,则可以用命令 syms x clear; ...
- Laravel5.5 生成测试数据
1.在database/factories/UserFactory.php 中添加 2.在tinker中生成数据 3.数据生成成功