iterator的实现原理
1.iterator遍历linkedlist集合
Iterator li = list.iterator();
while(li.hasNext()){
System.out.println(li.next());
}
这里可以看见Iterator li = list.iterator();
public Iterator<E> iterator() {
return new Itr();
}
那么这个iterator()方法是在它的抽象父类中,通过new Itr();去实例化这个Iterator对象。
public boolean hasNext() {
return cursor != size();
}
这里cursor初始化值为0;
当cursor等于size的时候,hasNext返回false;
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
那么这里可以一个很关键的一点它使用的还是get方法。
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
那我们现在看看get()方法是怎么遍历Node的无论无论这个index是多少?它都从first开始,或者last,取决于index < (size >> 1),这是个很巧妙的设计。看看index是不是超过size的一般,选择从后first还是last,这时我们也可以找到链表结构查询慢的根本原因,在于无论这个size有多大它都需要从first后last开始查询。远远慢于使用索引的arraylist。
2.iterator遍历ArrayList集合
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
事实上iterator();是在Arraylist和linkedlist的共同抽象父类abstractList中,唯有get();实现不同,所以Arraylist查询的速度要远远高于LinkedList.
2.iterator遍历hushmap集合
add();
Iterator<String> map = map.keySet().iterator();
while(map.hasNext()){
System.out.println(map.next());
}
那么这里就是遍历key一种方法,map.keySet().iterator();下面来看keyset()方法
public Set<K> keySet() {
Set<K> ks;
return (ks = keySet) == null ? (keySet = new KeySet()) : ks;
}
这里是通过keysett对象这里来看keySet类的iterator()方法
public final Iterator<K> iterator() { return new KeyIterator(); }
这里就通过KeyIterator()方法实现了这个Iterator接口,这时候我们看KeyIterator()是如何重写这个next()方法的。
public final K next() { return nextNode().key; }
}
那么这里返回nextNode().key;现在来看nextNode()
final Node<K,V> nextNode() {
Node<K,V>[] t;
Node<K,V> e = next;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (e == null)
throw new NoSuchElementException();
if ((next = (current = e).next) == null && (t = table) != null) {
do {} while (index < t.length && (next = t[index++]) == null);
}
return e;
}
这里就是遍历的核心内容,因为hashtable的关系,它的遍历需要判断table数组的链表中是否没有数据,如果没有数据而且table还没有到最大值,这时候我们的table数组下标加以1,开始遍历下一个数组,因为我们put一个对象时,它的存储方式完全根据对象的hashcode来存储的,本身它的取值是有顺序的,但是存储的时候是无序,所以取出来的数据也就没有顺序可言了。
map.values.iterator();
这里就很简单了,nextnode.key变成nextnode.value;
网上有人说遍历key和value的性能不一样,不知道为什么,看到这里,我认为性能是没有区别的。
关于hashSet的遍历
参照map.keyset().iterator();
iterator的实现原理的更多相关文章
- Java中Iterator(迭代器)实现原理
在Java中遍历List时会用到Java提供的Iterator,Iterator十分好用,原因是: 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结 ...
- Java集合之ArrayList和LinkedList的实现原理以及Iterator详解
ArrayList实现可变数组的原理: 当元素超出数组内容,会产生一个新数组,将原来数组的数据复制到新数组中,再将新的元素添加到新数组中. ArrayList:是按照原数组的50%来延长,构造一个初始 ...
- 迭代器Iterator的底层实现原理
第一步:没有接口的迭代器简单实现原理 package com.bjsxt.xiaofei; /** * 迭代器底层原理 * 方法: * hasNext() * next() * remove() * ...
- Iterator源码解读
//继承关系 public interface Inteator { boolean hasNext(); Object next(); } public interface Iterable { I ...
- List、Set集合系列之剖析HashSet存储原理(HashMap底层)
目录 List接口 1.1 List接口介绍 1.2 List接口中常用方法 List的子类 2.1 ArrayList集合 2.2 LinkedList集合 Set接口 3.1 Set接口介绍 Se ...
- Java | 集合(Collection)和迭代器(Iterator)
集合(Collection) 集合就是Java中提供的一种 空器,可以用来存储多个数据. 集合和数组都是一个容器,它们有什么区别呢? 数组的长度是固定的,集合的长度是可变的. 数组中存储的是同一类型的 ...
- cololection
package cn.bjsxt.col; /** * 简化迭代器原理 * hasNext * next * @author Administrator * */ public class MyArr ...
- 《算法》第二章部分程序 part 4
▶ 书中第二章部分程序,加上自己补充的代码,包括优先队列和索引优先队列 ● 优先队列 package package01; import java.util.Comparator; import ja ...
- java秀发入门到优雅秃头路线导航【教学视频+博客+书籍整理】
目录 一.Java基础 二.关于JavaWeb基础 三.关于数据库 四.关于ssm框架 五.关于数据结构与算法 六.关于开发工具idea 七.关于项目管理工具Mawen.Git.SVN.Gradle. ...
随机推荐
- Big Data架构师技能图谱
大数据通用处理平台 Spark Flink Hadoop 分布式存储 HDFS 资源调度 Yarn Mesos 机器学习工具 Mahout Spark Mlib TensorFlow (Google ...
- Servlet实现文件上传(深度)(二)
1.首先我们定义struts.properties的文件上传中的规则如下 struts.action.extension=action <!--以.action为我们提交的后缀名-->s ...
- Cookie的格式及组成
转自:http://blog.csdn.net/talking12391239/article/details/9665185 Cookie由变量名和值组成,类似JavaScript变量.其属性里既有 ...
- 5、手把手教你Extjs5(五)使用图标字体来美化按钮)
sencha 的例子中,有使用图标字体来美化按钮的例子,这个用起来又方便风格又统一,例如下图: 上面图标字体的使用方法也很简单,只要下载Font Awesome的css和图标文件,放到项目里就可以了. ...
- LPC1768的IIS通讯
IIS是飞利浦公司定义的一种用于音频传输的数字总线,LPC1768支持该总线, I2S接口为一条3线串行总线,含有1根数据线.1根时钟线和1根字选择信号线.基本的I2S连接具有一个主机(其总是为主机) ...
- linux下配置ip地址四种方法(图文)
(1)Ifconfig命令 第一种使用ifconfig命令配置网卡的ip地址.此命令通常用来零时的测试用,计算机启动后 ip地址的配置将自动失效.具体用法如下.Ipconfig ethx i ...
- springMVC+Hibernate配置
本文描述下 sypro 项目中使用 springMVC+Hibernate配置,初学SpringMVC做下简单整理解. 1.web项目首先我们要使用 web.xml文件将 spring配置引入进来 & ...
- flask-sqlalchemy relationship
http://www.ergo.io/blog/sqlalchemy-relationships-from-beginner-to-advanced class Cabinet(db.Model): ...
- bitmap 加载的时候出现OOM,nullpointer
1.OOM :对图片进行压缩,效果还不错:http://182.92.150.15:9876/static/server/topic_user/8068/201506/e5b37fec-0919-11 ...
- hack:选择符前缀法,样式属性前缀法
选择符前缀法 <style> *html .test{width:100px;} /*only for IE6*/ *+html .test{width:100px;}/*for IE6 ...