一、 Iterator 常用操作 next hasNext remove

先上源码:JDK8 简化版本,用于说明问题

 private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such public boolean hasNext() {
return cursor != size;
} public E next() {
int i = cursor;
Object[] elementData = ArrayList.this.elementData;
cursor = i + 1;
return (E) elementData[lastRet = i];
} public void remove() {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
} }

约定: Iterator  it = xxx.iterator();

疑惑1: 为什么不像 c++ 中 iterator 直接 *it 就可以获取当前值,java必须要 Object obj = it.next();

答:查看源码发现 调用 next 函数有两个作用,一个是获取当前 cusor 指向位置的元素,另一个是指针cusor 后移,并且 赋值 lastRet 变量(这里很关键)

疑惑二:为什么数组的最后一个元素进行 hasNext 返回真?

答:在迭代器中 可访问范围为 [0, size] 不是 [0, size)。因此传统意义数组的最后一个元素的下一个是 array[size], 尽管这个是无意义的,但是在迭代器中算一个特殊迭代器(类似 C++ . iterator.end() )

疑惑三:为什么删除元素不可以这么写?

 while(it.hasNext()){
  it.remove();
  it.next();
}

答:查看疑问一答中,next函数会赋值变量 lastRet ,这个变量对于 remove 函数相当重要。 因此在首次进入 while 循环的时候, laseRet = -1 (默认状态),因此不能直接进行 remove ,数组越界。

所以正确的应该是

 while(it.hasNext()){
it.next();
it.remove();
}

二、 ListIterator 中 lastIndex previousIndex previous

先上源码:JDK8 简化版本,用于说明问题

      public boolean hasPrevious() {
return cursor != 0;
} public int nextIndex() {
return cursor;
} public int previousIndex() {
return cursor - 1;
} public E previous() {
int i = cursor - 1;
Object[] elementData = ArrayList.this.elementData;
cursor = i;
return (E) elementData[lastRet = i];
}

疑惑一: 如何获取正确的 前一个元素的下标值和后一个元素的下标值?

答:先看一段代码:

 public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>(Arrays.asList(4, 5, 6, 7, 8));
ListIterator<Integer> it = list.listIterator();
System.out.println(it.previousIndex());
System.out.println(it.nextIndex());
}
//output
-1
0

显然输出并不正确,我们期望得到的是 -1 1

解释这个现象看源码,我们发现

① previousIndex 和 nextIndex 只能使用在后向移动的迭代器中,尽管ListIterator 是一个双向迭代器

② previousIndex 和 nextIndex 返回值依赖于 cursor 当前的数值,因此 上面代码中 cursor=0,所以 得出错误结果。要想获取下一个索引的正确之,我们需要 调用一次 next 函数帮助我们调整 cursor

这样即可获取我们期望的数值:

 public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>(Arrays.asList(4, 5, 6, 7, 8));
ListIterator<Integer> it = list.listIterator();
System.out.println(it.previousIndex());
it.next();
System.out.println(it.nextIndex());
}
//output 
-1
1

注: previous 和 next 函数中 cusor 移动不一样,

next函数是获取了当前值但是 cursor 已经移动到了下一个,相当于 return array[cursor++];

previous 函数是移动到前一个并且获取值   ,相当于 return array[--cursor];

												

Java Iterator ListIterator 理解的更多相关文章

  1. Java Iterator, ListIterator 和 foreach语句使用

    Java Iterator, ListIterator 和 foreach语句使用 foreach语句结构: for(part1:part2){part3};  part2 中是一个数组对象,或者是带 ...

  2. JAVA中ListIterator和Iterator详解与辨析

    在使用Java集 合的时候,都需要使用Iterator.但是java集合中还有一个迭代器ListIterator,在使用List.ArrayList. LinkedList和Vector的时候可以使用 ...

  3. java:集合输出Iterator,ListIterator,foreach,Enumeration

    //集合输出,集合的四种输出 Iterator, ListIterator, foreach, Enumeration 只要碰到集合,第一输出选择是Iterator类. Iterator<E&g ...

  4. Java 集合深入理解(8):AbstractSequentialList

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天有点无聊,来学学 AbstractSequentialList 解解闷 吧! AbstractSequentialLi ...

  5. Java 集合深入理解(7):ArrayList

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情有点美丽,学学 ArrayList 放松下吧! 什么是 ArrayList ArrayList 是 Java 集合 ...

  6. Java 集合深入理解(6):AbstractList

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情比天蓝,来学学 AbstractList 吧! 什么是 AbstractList AbstractList 继承自 ...

  7. Java 集合深入理解(4):List<E> 接口

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 蓝瘦!香菇! 连着加班几天,醉了.学学 List 放松下! 在 Java 集合深入理解:Collection 中我们熟悉了 ...

  8. 源码(08) -- java.util.ListIterator<E>

    java.util.ListIterator<E> 源码分析(JDK1.7) ------------------------------------------------------- ...

  9. 关于java中Stream理解

    关于java中Stream理解 Stream是什么 Stream:Java 8新增的接口,Stream可以认为是一个高级版本的Iterator.它代表着数据流,流中的数据元素的数量可以是有限的, 也可 ...

随机推荐

  1. Highcharts error #14: www.highcharts.com/errors/14

    错误原因:数据类型错误,需要的是Number类型,传入的却是String 以为为官网说明: Highcharts Error #14 String value sent to series.data, ...

  2. Linux服务器性能评估与优化(一)

    网络内容总结(感谢原创) 1.前言简介 一.影响Linux服务器性能的因素   1. 操作系统级         性能调优是找出系统瓶颈并消除这些瓶颈的过程. 很多系统管理员认为性能调优仅仅是调整一下 ...

  3. ArcGIS for Server安全与LDAP配置

    ArcGIS for Server安全与LDAP配置 1.安全性概述 ArcGIS Server使用基于角色的访问控制来管理对受保护资源的访问.访问GIS资源的权限只能分配给角色.单独的用户只能通过从 ...

  4. 01_JMS概述

    [以前的通信技术的局限性] 在大规模和复杂的分布式系统中,传统的RMI.DCOM等中间件通信技术逐渐有了局限性,如下: 1.同步通信:客户发出调用后,必须等待服务对象完成处理并返回结果才能继续执行. ...

  5. js 常用排序整理

    排序: 1. 内部排序: (1). 交换排序: 1). 冒泡排序 稳定 一次比较相邻两个元素的大小,顺序错误的,将其位置互换 (从高位到低位 或者 从低位到高位) 初始版: var array = [ ...

  6. uwsgi特性

    uwsgi 特性 官网参考 X-Sendfile仿真 即使前端 代理/webserver 不支持X-Sendfile (或者不能访问静态资源),可以使用 uwsgi 内部的 offloading 来模 ...

  7. Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? 线程的sleep()方法和yield()方法有什么区别?

    Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间 ...

  8. PHP腾讯与百度坐标转换

    function coordinate_switch($a,$b){//百度转腾讯坐标转换 $a = Latitude , $b = Longitude $x = (double)$b - 0.006 ...

  9. bind 详解

    请看我的有道云笔记: http://note.youdao.com/noteshare?id=eaf4194473cf4294776fbc263ffe6b89&sub=5CB214C594E0 ...

  10. Python3条件控制语句

    Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. if语句 if 条件: 代码块 elif 条件: 代码块 else: 代码块 python中用elif ...