文档章节

Java Iterator遍历List集合

spilledyear
 spilledyear
发布于 2017/09/08 14:20
字数 799
阅读 15
收藏 0

什么是迭代器

迭代器是一个对象,它的工作是遍历并且选择序列中的对象(比如一个ArrayList),而客户端程序员不必知道或关心该序列底层的结构。此外,迭代器通常被称为轻量级对象:创建它的代价很小,经常可以看到对迭代器有一些奇怪的限制,例如,Java中的iterator只能单向移动,这个Iterator只能用来:

  • 使用iterator()方法要求容器返回一个Iterator对象。Iterator将准备好返回序列的第一个元素。
  • 使用next()或者序列中的写一个元素。 -使用hasNext()方法检查序列中是否还有元素。
  • 使用remove()方法将讲迭代器新返回的元素删除。

实例分析

package com.hand.hsp;

import java.util.*;

/**
 * Created by Moxie on 2016/12/25.
 */
public class TestIterator {

    public static void main(String[] args){
        List<Integer> list = new ArrayList<Integer>();
        for(int i = 0 ; i < 10 ; i++){
            list.add(i);
        }
        //调用ArrayList的iterator()方法返回一个 Iterator 对象
        Iterator<Integer> iterator = list.iterator();
        //从第一个元素开始遍历,每次获取一个新的元素
        while(iterator.hasNext()){
            int number = iterator.next();
            System.out.print(number + "        ");
        }
        System.out.println();

        int k = 0;
        iterator = list.iterator();
        while(k++ < 5 && iterator.hasNext()){
            /**
             * 注意下面这两条语句的顺序,第一次执行iterator.next()的时候取到的是第一个元素,然后再remove。
             * 如果顺序相反,则会抛出异常Exception in thread "main" java.lang.IllegalStateException,
             * 意思就是:在不合理或不正确时间内唤醒一方法时出现的异常信息。换句话说,
             * 即 Java 环境或 Java 应用不满足请求操作。
             */
            iterator.next();
            iterator.remove();
        }

        while(iterator.hasNext()){
            int number = iterator.next();
            System.out.print(number + "        ");
        }

    }


}

原理分析

Iterator的用途我们已经看到了,那么,它究竟是怎么实现的呢?这时候我们找到Iterator接口,发现它只声名了下面这几个方法

然后我们再找到ArrayList的iterator()方法,看看它是怎么实现的,从 833行开始,到903行(JDK1.8)

public Iterator<E> iterator() {
        return new Itr();
    }

    /**
     * An optimized version of AbstractList.Itr
     */
    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
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        @Override
        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer<? super E> consumer) {
            Objects.requireNonNull(consumer);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            cursor = i;
            lastRet = i - 1;
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

看了源代码,是不是觉得有点熟悉?它是通过一个名叫 Itr 的内部类实现的,逻辑代码都写在内部类里面。这不是那种什么设计模式吗?迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。我们平时调用的iterator()方法,就是这样实现的,看了源码是不是觉得清爽了好多?

© 著作权归作者所有

共有 人打赏支持
spilledyear
粉丝 0
博文 8
码字总数 4806
作品 0
ArrayList和LinkedList的几种循环遍历方式及性能对比分析

最新最准确内容建议直接访问原文:ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据Arr...

Trinea
2013/10/31
0
1
hibernate 和JDBC的比较(转)

刚开始学习JAVA时,认为Hibernate是一个很神圣的东西,好像是会了SSH,就能走遍全世界一样。记得曾经在枫叶面试的时候,我们几个同学出还说这个公司怎么这么的落后,还有JDBC,没有一点上进心...

qq22734179
2014/04/26
0
0
Java集合框架之Iterator和ListIterator

一、前言 迭代器是一个对象,它可以让你遍历一个容器并且有选择性的删除容器中的元素,而我们不需要知道容器的内部结构.Java有两种原生的迭代器:Iterator和ListIterator, 其中ListIterator继承...

JackieYeah
2014/04/08
0
0
Java集合框架的知识总结(1)

说明:先从整体介绍了Java集合框架包含的接口和类,然后总结了集合框架中的一些基本知识和关键点,并结合实例进行简单分析。 1、综述 所有集合类都位于java.util包下。集合中只能保存对象(保...

dong.li
2012/04/24
0
0
Java学习之Iterator(迭代器)的一般用法

问题: 看老大的代码需要取list里面每个元素的时候,都是 Iterator it = list.iterator(); while (it.hasNext()) { personnelID= (String) it.next(); } 这样比我直接写for(int i=0;i<list.......

chuiyuan
2014/04/28
0
1

没有更多内容

加载失败,请刷新页面

加载更多

win10下端口被占用解决办法

win10下端口被占用解决办法 昨天还好好的tomcat,今天启动时候发现tomcat无法启动,看报错信息显示8080端口被占用。 解决办法如下:按win+R输入cmd打开控制台,输入 netstat -ano|findstr 8...

DemonsI
13分钟前
1
0
yum apt chrome 常用软件的SOCKS 代理设置

yum 设置: 在/etc/yum.conf 增加一行,内容为: 在apt-get (apt) 上使用socks代理 chrome socks代理:

idoz
14分钟前
0
0
因 php 默认的 url encode 编码标准引发的一个问题

先看常用的校验请求合法性的一个方式 function createToken($params) { $secretKey = 'secretKey'; ksort($params); $query = http_build_query($params); $token = md5......

anoty
18分钟前
5
0
微信小程序页面栈管理

页面路由 在小程序中所有页面的路由全部由框架进行管理。 页面栈 框架以栈的形式维护了当前的所有页面。当发生路由切换的时候,页面栈的表现如下: 路由方式 页面栈表现 初始化 新页面入栈 ...

昙花一现
54分钟前
2
0
es6 let使用总结

中午偷个闲做个es6let的使用总结 作用域块 在作用域块中声明的变量不受外部的影响,见例子 {let a= 10;{let a= 20;console.log('子作用域', a);// 20}console.log('父作用域', a);// 10...

莫西摩西
55分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部