文档章节

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()方法,就是这样实现的,看了源码是不是觉得清爽了好多?

© 著作权归作者所有

共有 人打赏支持
上一篇: Java多线程(一)
下一篇: Java 遍历Map集合
spilledyear
粉丝 1
博文 8
码字总数 4806
作品 0
私信 提问
ArrayList和LinkedList的几种循环遍历方式及性能对比分析

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

Trinea
2013/10/31
0
1
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
Java集合框架的知识总结(1)

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

dong.li
2012/04/24
0
0
Java Connection集合分析之List

Java Connection集合家庭分析 Java集合大致可以分为Set、List、Queue和Map四种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map则代表具有映射关系的集合,Java 5 ...

我爱春天的毛毛雨
11/14
0
0
Java集合框架(一)——集合概述

本文概述 本篇文章将分三块内容对Java中的集合框架进行介绍: 一. 集合框架相关概念 二. 集合体系通用方法 三. 集合遍历—Iteractor 一. 集合框架相关概念 集合:用于存储多个对象的容器 1....

Mr_Yanger
2017/11/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

EOS官方钱包keosd

EOS官方钱包的名称是keosd,它负责管理你的私钥,并且帮你进行交易的签名。 不过不幸的是,keosd钱包对普通用户并不友好,它是一个命令行程序,目前还没有像以太坊的mist那样的图形化界面,而...

汇智网教程
今天
9
0
ArrayList的实现原理以及实现线程安全

一、ArrayList概述 ArrayList是基于数组实现的,是一个动态的数字,可以自动扩容。 ArrayList不是线程安全的,效率比较高,只能用于单线程的环境中,在多线程环境中可以使用Collections.syn...

一看就喷亏的小猿
今天
12
0
Netty 备录 (一)

入职新公司不久,修修补补1个月的bug,来了点实战性的技术---基于netty即时通信 还好之前对socket有所使用及了解,入手netty应该不是很难吧,好吧,的确有点难,刚看这玩意的时候,可能都不知道哪里...

_大侠__
昨天
17
0
Django简单介绍和用户访问流程

Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。 Django是一个开放源代码的Web应用框架,由Python写成。 Django遵守BSD版权,初...

枫叶云
昨天
25
0
Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)

应用场景 之前我们已经通过《Spring Cloud Stream消费失败后的处理策略(一):自动重试》一文介绍了Spring Cloud Stream默认的消息重试功能。本文将介绍RabbitMQ的binder提供的另外一种重试...

程序猿DD
昨天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部