Java容器解析系列(1) 迭代的进化——从Enumeration到Iterator
在Java中,对于所有的Collection,都有一个特性,可以通过迭代器来遍历和删除其中的元素,因为Collection接口继承自Iterable接口.
public interface Collection<E> extends Iterable<E>
Iterable接口中只有一个方法:
/**
该接口的实现类可以被用于"foreach"语句
* @since 1.5
*/
public interface Iterable<T> {
// 返回对象的迭代器
Iterator<T> iterator();
}
Iterable接口除了提供iterator()方法返回迭代器之外,所有实现了Iterable接口的类都可以通过foreach语句调用.
其实,foreach语句遍历Collection的本质就是对Iterable接口的调用.
关于foreach的具体原理,可以参考:
Java for-each 原理相关解析
java foreach原理
接下来看iterator()方法返回的Iterator接口,其为具体的迭代器实现提供了规范和指引:
/**
对指定Collection的迭代器,用于替换之前的迭代器接口Enumeration.
Iterator与Enumeration的区别在于:
1. Iterator允许在well-defined semantics的情况下删除Collection中的元素(这个是可选操作);
2. 方法名更加精炼;
well-defined semantics:生硬一点可以翻译为"语义良好的",这里为了不引起误解,使用原英文;
@since 1.2
*/
public interface Iterator<E> {
// 如果还有更多元素,返回true,否则返回false;
// 如果返回true,调用next()会返回下一个元素;
boolean hasNext();
// 返回迭代过程中的下一个元素,如果没有下一个元素,抛出NoSuchElementException;
// hasNext()返回true是next()会返回下一个元素的保证;
E next();
// 移除Collection中上一次调用next()方法返回的对象,这是一个可选操作(optional operation);
// 如果调用remove()之前没有调用next()方法,抛出UnsupportedOperationException;
// 如果调用next()之后,调用了remove()方法,在下一次调用remove()方法之前,如果没有再次调用next()方法,则remove()方法抛出IllegalStateException;
// 后面这两条应当视为well-defined semantics的一些规定了,除此之外remove()方法还可能涉及到fast-fail机制等;
void remove();
}
Iterator包含的方法已经将其作为一个迭代器的本质表现得一丝不挂.而其诞生的目的是用于替换老旧的Enumeration接口.
本篇只讲Iterator接口的jdk设计,至于其使用,我们在讲述具体Collection时再陈述.因为每个具体的实现都不同,且其中还涉及到fast-fail机制等.
基于之前读过的很多资料还是有关于Enumeration的使用,让人心烦,所以还是看一下这个接口的具体内容.
/**
一个实现该Enumeration接口的对象能够遍历一系列元素.每次调用nextElement返回这个系列中的下一个元素;
这个类与Iterator的功能重复,新的迭代器推荐使用Iterator实现;
* @since JDK1.0
*/
public interface Enumeration<E> {
// 如果还有更多元素,返回true,否则返回false;
// 如果返回true,调用next()方法会返回下一个元素;
// 这个方法对应Iterator的hasNext()方法;
boolean hasMoreElements();
// 返回迭代过程中的下一个元素,如果没有下一个元素,抛出NoSuchElementException;
// hasMoreElements()返回true是nextElement方法会返回下一个元素的保证;
// 该方法对应Iterator的next()方法;
E nextElement();
}
Enumeration 接口自jdk1.0就添加进来了,常见的使用Enumeration的地方包括:
- 在Vector中用于遍历元素;
- 在Hashtable用于对keys和values的遍历;
- 在SequenceInputStream用于指定多个InputStream进行对象构造;
Java容器解析系列(1) 迭代的进化——从Enumeration到Iterator的更多相关文章
- Java容器解析系列(0) 开篇
最近刚好学习完成数据结构与算法相关内容: Data-Structures-and-Algorithm-Analysis 想结合Java中的容器类加深一下理解,因为之前对Java的容器类理解不是很深刻, ...
- Java容器解析系列(11) HashMap 详解
本篇我们来介绍一个最常用的Map结构--HashMap 关于HashMap,关于其基本原理,网上对其进行讲解的博客非常多,且很多都写的比较好,所以.... 这里直接贴上地址: 关于hash算法: Ha ...
- Java容器解析系列(13) WeakHashMap详解
关于WeakHashMap其实没有太多可说的,其与HashMap大致相同,区别就在于: 对每个key的引用方式为弱引用; 关于java4种引用方式,参考java Reference 网上很多说 弱引用 ...
- Java容器解析系列(10) Map AbstractMap 详解
前面介绍了List和Queue相关源码,这篇开始,我们先来学习一种java集合中的除Collection外的另一个分支------Map,这一分支的类图结构如下: 这里为什么不先介绍Set相关:因为很 ...
- Java容器解析系列(7) ArrayDeque 详解
ArrayDeque,从名字上就可以看出来,其是通过数组实现的双端队列,我们先来看其源码: /** 有自动扩容机制; 不是线程安全的; 不允许添加null; 作为栈使用时比java.util.Stac ...
- Java容器解析系列(8) Comparable Comparator
Comparable和Comparator接口是两个用于对对象进行大小比较的接口,在java集合相关类中,也被经常地使用到. 关于其使用,可以参考网络上的其他博客(没什么好说的);这里阐述关于这两个接 ...
- Java容器解析系列(9) PrioriyQueue详解
PriorityQueue:优先级队列; 在介绍该类之前,我们需要先了解一种数据结构--堆,在有些书上也直接称之为优先队列: 堆(Heap)是是具有下列性质的完全二叉树:每个结点的值都 >= 其 ...
- Java容器解析系列(6) Queue Deque AbstractQueue 详解
首先我们来看一下Queue接口: /** * @since 1.5 */ public interface Queue<E> extends Collection<E> { / ...
- Java容器解析系列(4) ArrayList Vector Stack 详解
ArrayList 这里关于ArrayList本来都读了一遍源码,并且写了一些了,突然在原来的笔记里面发现了收藏的有相关博客,大致看了一下,这些就是我要写的(╹▽╹),而且估计我还写不到博主的水平,这 ...
随机推荐
- Linux实现VLAN
交换机的端口有两种配置模式:Access和Trunk. Access口:端口属于VLAN,VLAN ID 1~4096.直接与计算机网卡相连,流入该口的数据包都被打上VLAN的标签. Trunk口:允 ...
- mybites
[mybatis-spring] http://www.mybatis.org/spring/zh/index.html 使用spring mybatis 中间件 方便使用 mybatis [myba ...
- Python基础(三)文件操作
[对文件进行循环操作] fw = open('nhy','w') for line in fw: print('line:',line) #直接循环文件对象,每次循环的时候就是取每一行的数据 fw ...
- DataTable插件 后台分页 (服务器端分页)
<script type="text/javascript"> var persontable; var personQueryCondition = { ...
- Windows安装MySQL5.7.23 zip包
工欲善必先利其器 # 环境: Win7旗舰版 + MySQL5.7.23 # 用到的命令: mysqld --initialize -- 初识化 mysqld --install -- 添加到Wind ...
- nginx 反向代理和正向代理功能 第六章
一:Nginx作为正向代理服务器: 1.正向代理:代理(proxy)服务也可以称为是正向代理,指的是将服务器部署在公司的网关,代理公司内部员工上外网的请求,可以起到一定的安全作用和管理限制作用,正向代 ...
- 剑指offer(35)数组中的逆序对
题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...
- WinForm动态查询
WinForm 动态查询 1. 使用场景 在对数据进行筛选, 包含多个筛选字段时适用. 2. 接口设计 /// <summary> /// 定义可作为追加到 WHERE 子句的控件接口 / ...
- (转载)【UGUI】侧面滑出的菜单栏,宽度自适应
首先看下项目效果 实现效果 发现实现效果并不难,利用动画(iTween)+UGUI 有一个长按的判断处理即可 附上项目和代码 using System.Collections; using Syste ...
- sql添加一个list的查询条件
编程中往往会有需要对某个list的值进行查询的需求,而将一个list作为查询条件,我所知道的有两种方法: 1.for循环遍历,每次循环一个sql,每次查list中一个条件的数据,最后累加 ...(最基 ...