Iterator迭代器

2023-05-16

1.迭代器的概述

迭代器:是一种通用的遍历集合,取出集合中元素的方式
迭代器由来:
集合有很多种,每种集合的数据结构是不同的(数组,链表,哈希表…),集合取出元素的方式也不同
我们不可能为每种集合都定义一种取出元素的方式,浪费
所以我们就可以使用迭代器,是集合通用的取出元素的方式
迭代器取出元素的原理:
判断集合中还有没有元素,有就取出来
再判断集合中还有没有元素,有再取出来
一直判断到集合中没有元素为止,这种取出元素的方式叫迭代


java.util.Iterator接口:对 collection 进行迭代的迭代器。
Iterator接口中的常用方法:
boolean hasNext() 判断集合中还有没有元素;有返回true,没有返回false
E next() 取出集合中的元素

Iterator是一个接口无法创建对象使用,使用Iterator接口的实现类对象,Iterator接口的实现类对象是每个集合的内部类(了解)
我们可以使用Collection接口中的方法iterator获取迭代器Iterator接口的实现类对象
Iterator iterator() 返回在此 collection 的元素上进行迭代的迭代器。
注意:
我们无需关注iterator方法返回的是Iterator接口的哪个实现类对象,我们只需要会使用Iterator接口来接收这个实现类对象即可(多态)

2.迭代器的基本使用
迭代器方法
在这里插入图片描述
迭代==>遍历集合
在这里插入图片描述

package com.itheima.demo02Iterator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
    迭代器的基本使用(重点)
    使用步骤:
        1.使用Collection接口中的方法iterator获取迭代器的实现类对象
        2.使用迭代器Iterator接口中方法hasNext判断集合中有没有元素
        3.集合中有元素,使用next方法取出元素
 */
public class Demo01Iterator {
    public static void main(String[] args) {
        Collection<String> coll = new ArrayList<>();
        coll.add("张三");
        coll.add("李四");
        coll.add("王五");
        coll.add("赵六");
        coll.add("田七");

        //1.使用Collection接口中的方法iterator获取迭代器的实现类对象
        //多态 接口    变量名 = 实现类对象();
        Iterator<String> it = coll.iterator();

        /*
            我们发现使用迭代器取出集合中的元素是一个重复的过程
            所以可以使用循环优化,不知道集合中有多少元素
            所以使用while循环,循环结束的条件, it.hasNext方法返回false
         */
        //2.使用迭代器Iterator接口中方法hasNext判断集合中有没有元素
        while (it.hasNext()){
            //3.集合中有元素,使用next方法取出元素
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("---------------------------------------");
        //迭代器只能使用一次,想要再次使用迭代器,必须重新获取迭代器对象
        Iterator<String> it2 = coll.iterator();
        while (it2.hasNext()){
            //3.集合中有元素,使用next方法取出元素
            String s = it2.next();
            System.out.println(s);
        }
         /*
        //2.使用迭代器Iterator接口中方法hasNext判断集合中有没有元素
        boolean b = it.hasNext();
        System.out.println(b);//true

        //3.集合中有元素,使用next方法取出元素
        String s = it.next();
        System.out.println(s);//张三

        b = it.hasNext();
        System.out.println(b);//true
        s = it.next();
        System.out.println(s);//李四

        b = it.hasNext();
        System.out.println(b);//true
        s = it.next();
        System.out.println(s);//王五

        b = it.hasNext();
        System.out.println(b);//true
        s = it.next();
        System.out.println(s);//赵六

        b = it.hasNext();
        System.out.println(b);//true
        s = it.next();
        System.out.println(s);//田七

        b = it.hasNext();
        System.out.println(b);//false
        //s = it.next();//NoSuchElementException 没有这个元素异常
     */
        System.out.println("---------------------------------------");
        for(Iterator<String> it3 = coll.iterator();it3.hasNext();){
            String s = it3.next();
            System.out.println(s);
        }

    }
}

迭代器只能使用一次,想要再次使用迭代器,必须重新获取迭代器对象

3.迭代器的执行原理
在这里插入图片描述
🎗迭代器的并发修改异常
在这里插入图片描述
在使用迭代器的时候,不能添加(或者修改)集合中的元素,要不然会报错
在这里插入图片描述
迭代器进行使用的时候,集合不能进行删除(或者添加)元素(要不然就会出现并发修改异常),但是,由迭代器主动删除就不会报错;要是想在使用迭代器的时候向集合中添加元素,需要用到迭代器下面的一个子接口(listInterator),它里面有添加元素的方法。

(1)1.已知使用迭代器遍历集合的代码

public class Demo02Iterator {
    public static void main(String[] args) {
        //创建集合对象,往集合中添加元素
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        //使用迭代器遍历list集合
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
            
            /*
                需求: 增加一个判断,如果取出的元素s是"ccc"
                就给集合添加一个新的元素"itcast"
             */
            /*if("ccc".equals(s)){
                list.add("itcast");
            }*/
            
            /*
                需求: 增加一个判断,如果取出的元素s是"ccc"
                就把集合中的元素"ddd"删除
             */
            if("ccc".equals(s)){
                list.remove("ddd");
            }
        }
    }
}

(2)出现的问题

程序抛出了迭代器的并发修改异常ConcurrentModificationException
在这里插入图片描述

(3)问题的分析
在使用迭代器遍历集合的过程中,对集合的长度进行了修改,迭代器就会抛出并发修改异常

  • 添加元素
    在这里插入图片描述
  • 删除元素
    在这里插入图片描述

(4)问题解决办法

第一种解决办法:
在遍历集合的同时,不修改集合长度

public class Demo01Iterator {
    public static void main(String[] args) {
        //创建集合对象,往集合中添加元素
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        //使用迭代器遍历list集合
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
    }
}

程序运行结果:
在这里插入图片描述

第二种解决办法:
Iterator接口中有一个方法叫remove,作用也是删除集合中的元素
void remove() 删除使用next方法取出的集合中的元素

public class Demo03Iterator {
    public static void main(String[] args) {
        //创建集合对象,往集合中添加元素
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        //使用迭代器遍历list集合
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);

            /*
                需求: 增加一个判断,如果取出的元素s是"ccc"
                就把集合中的元素"ccc"删除
             */
            if("ccc".equals(s)){
                it.remove();//使用迭代器删除集合中元素的方法,删除it.next方法取出的元素
            }
        }
        System.out.println(list);
    }
}

​程序运行结果:
在这里插入图片描述

第三种解决办法:
Iterator接口有一个子接口叫ListIterator接口,在ListIterator接口中定义了往集合中添加元素的方法
​ public interface ListIterator extends Iterator
void add(E e) 将指定的元素插入列表(可选操作)。 ListIterator接口特有的方法
​​ void remove() 删除使用next方法取出的集合中的元素

public class Demo04Iterator {
    public static void main(String[] args) {
        //创建集合对象,往集合中添加元素
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        //使用List接口中的方法listIterator获取ListIterator迭代器接口的实现类对象
        ListIterator<String> lit = list.listIterator();
        //使用ListIterator迭代器中的方法hasNext判断集合中是否还有元素
        while (lit.hasNext()){
            //使用ListIterator迭代器中的方法next取出集合中的元素
            String s = lit.next();
            System.out.println(s);

            /*
                需求: 增加一个判断,如果取出的元素s是"ccc"
                就给集合添加一个新的元素"itcast"
             */
            if("ccc".equals(s)){
                lit.add("itcast");//使用迭代器中的add方法,往集合中添加元素
            }
        }

        System.out.println(list);
    }
}

程序运行结果:
在这里插入图片描述

总结
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Iterator迭代器 的相关文章

  • Python 中的循环列表迭代器

    我需要迭代一个循环列表 可能很多次 每次都从最后访问的项目开始 用例是连接池 客户端请求连接 迭代器检查指向的连接是否可用并返回它 否则循环直到找到可用的连接 我怎样才能在Python中巧妙地做到这一点 If you instead nee
  • 如何检查传递的迭代器是否是随机访问迭代器?

    我有以下代码 它执行一些迭代器算术 template
  • 向量迭代器

    我有以下代码 vector
  • 如何实现 STL 风格的迭代器并避免常见的陷阱?

    我创建了一个集合 我想为其提供一个 STL 风格的随机访问迭代器 我正在寻找迭代器的示例实现 但没有找到 我知道需要 const 重载 and 运营商 迭代器 STL 风格 的要求是什么 还有哪些其他需要避免的陷阱 如果有 附加上下文 这是
  • 调试时无法进入迭代器块 (C#)

    我正在尝试调试从单元测试项目执行的代码 但是当我尝试进入一个方法时 它只是直接传递到下一行 并且不会命中该方法内的断点 该方法位于不同项目中的一个类上 但所有代码都是在调试模式下构建的 我已经尝试清理和重建解决方案 但没有任何乐趣 然而 自
  • Boost Property_Tree迭代器,如何处理它们?

    抱歉 我之前问过关于同一主题的问题 但我的问题涉及那里描述的另一个方面 如何迭代提升 https stackoverflow com questions 4586768 how to iterate a boost property tre
  • 删除元素时映射迭代器如何失效? [复制]

    这个问题在这里已经有答案了 使用擦除方法时 迭代器何时以及如何在映射中失效 例如 std map lt int int gt aMap aMap 33 1 aMap 42 10000 aMap 69 100 aMap 666 1 std m
  • C++迭代器和反向迭代器

    我正在写一个iterator 实际上是const iterator对于我当前的对象 我还想创建一个reverse const iterator also 我环顾四周 想看看如何做到这一点 然后我偶然发现this http www cplus
  • Julia - 迭代字典中的键组合

    有没有一种巧妙的方法来迭代字典中的键组合 我的字典有这样的值 1 gt 1 2 2 3 gt 15 3 gt 6 7 8 4 9 11 gt 3 我需要做的是获取所有长度的键组合1 n where n可能是FX 3 就像上面的例子一样 我想
  • 如何解决 pandas 读取大 csv 文件时的内存问题

    我有一个 100GB 的 csv 文件 其中有数百万行 我需要在 pandas 数据框中一次读取 10 000 行 并将其分块写入 SQL 服务器 我按照建议使用了 chunksize 以及 iteartorhttp pandas docs
  • 将多个参数传递给concurrent.futures.Executor.map?

    The concurrent futures Executor map http docs python org py3k library concurrent futures html concurrent futures Executo
  • 为什么即将推出的 Ranges 库不支持范围内的容器初始化?

    介绍 随着即将推出的 Ranges 库 用两个迭代器表示范围的需要几乎消失了 例如 代替 if std equal begin foo end foo begin bar end bar we have if std ranges equa
  • 从向量中删除向量::end

    当我使用时它工作正常吗 什么也不做 vector
  • 我怎样才能制作自己的惰性迭代器?

    我正在创建一个生成大量数据的 C 11 类 该数据当前来自数据库 无法完全放入内存中 我想为用户提供一个行为类似于常规 STL 迭代器的迭代器 但这会很懒 更准确地说 我可以做这样的事情 for auto item big bunch of
  • java.util.ConcurrentModificationException 和迭代?

    我对数组列表和迭代器非常陌生 这是我第一次遇到这个异常 我有一个 ArrayList u 我想做以下算法 for Character c u if k 1 base case if isAnswer s u get 0 System out
  • removeIf 实现细节

    我有一个我无法理解的小实施细节问题ArrayList removeIf 我认为我不能在没有先决条件的情况下简单地这么说 因此 实施基本上是bulk remove 不像ArrayList remove 一个例子应该会让事情更容易理解 假设我有
  • Python range() 和 zip() 对象类型

    我了解功能如何range and zip 可以在 for 循环中使用 然而我期望range 输出一个列表 很像seq在 Unix shell 中 如果我运行以下代码 a range 10 print a 输出是range 10 表明它不是一
  • 如何在 Java 中获得列表的反向列表视图?

    我想在列表上有一个反向列表视图 与List sublist提供列表上的子列表视图 是否有一些函数可以提供此功能 我不想复制该列表 也不想修改该列表 在这种情况下 如果我能在列表上至少获得一个反向迭代器就足够了 另外 我知道如何自己实现这一点
  • iOS 循环对象的属性并添加操作

    我有一个具有几个类似属性的类 UISliders 我想添加用户开始和结束使用每个滑块时的操作 每个滑块都将链接到同一个选择器 因此我考虑只是迭代它们 而不是编写 10 个几乎相同的代码块 问题是 最有效的方法是什么 我尝试过这样的事情 在运
  • C++ std::vector 搜索值

    我正在尝试优化std vector 搜索 基于索引的迭代向量并返回与 搜索 条件匹配的元素 struct myObj int id char value std vector

随机推荐

  • Win10只能安装GPT磁盘的解决办法

    最近帮同事重装系统时 xff0c 遇到了之前没遇到过的问题 无论是微软官方的U盘制作工具还是MSDN下载的镜像加上rufus都无法解决的问题 xff0c 那就是在选择安装磁盘时会提示无法安装 xff0c 点击错误详细会出现下面的提示框 xf
  • C语言中常用运算符

    C语言中常用到的运算符主要有算数运算符 逻辑运算符 位运算发 关系运算符和其它的 一 算数运算符 主要是我们在数学运算中使用的一些加减乘除运算符 xff0c 但是有几个运算符与我们数学中的不 太一样 xff08 以下会说明 xff09 xf
  • 如何下载Ubuntu 20.04并运行在VM虚拟机上

    第一步 下载Ubuntu镜像文件 下载Ubuntu的镜像 xff0c 我们首先想到的就是去官网下载 xff0c 但是由于服务器在国外 xff0c 下载速度可能只有几KB S 甚至压根就下载不了 其实我们有更好的选择 那就是选择我们国内的一些
  • Unbutntu18.04 caffe在make编译时出现对‘cv::imread(cv::String const&, int)’未定义的引用 解决方案

    在CAFFE编译时会出现如下错误 xff1a CXX LD o build release tools caffe bin build release lib libcaffe so xff1a 对 cv imread cv String
  • yolov5返回坐标

    yolov5返回坐标 yolov5目前已更新到v6版 xff0c 上面up主的文章是以前的版本 xff0c 代码对应不上 xff0c 所以特地在此更新一下 xff1a 参考链接 xff1a https blog csdn net weixi
  • ISD9160学习笔记02_搭建NuMicro开发环境

    http blog csdn net iotisan article details 53166357 所谓学习笔记 xff0c 不能免俗地总会讲到开发环境 嵌入式这一行就是这样 xff0c 每做一个新方案 xff0c 就得学习它的CPU
  • RS232不能通信的问题

    RS232不能通信 xff0c 根据PCB图检查了硬件电路是否导通 xff0c 短路状态使用串口工具发送消息收到消息可以收发 xff0c 编程方面大概率无误 由原理图可见 xff0c 地 TXD和RXD设计错误 xff0c 没有反着接 用杜
  • NRF24L01+实现一对一数据双向传输

    NRF24L01 43 实现一对一数据双向传输 目录说明带负载数据ACK的双向通信配置NRF24L01 43 的收发程序收发双方数据的处理测试代码和结果 目录 说明 最近在diy四轴飞行器的时候 xff0c 需要实现四轴和遥控器之间的双向通
  • RT-Thread开启串口.中断和DMA接收(手把手教学)

    1 串口介绍 串口是指数据一位一位地顺序传送 xff0c 其特点是通讯线路简单 xff0c 只要一对传输线就可以实现双向通信 xff08 可以直接利用电话线作为传输线 xff09 xff0c 从而大大降低了成本 xff0c 特别适用于远距离
  • stm32使用MPU6050读取温度值验证I2C

    通过MPU6050测温来进行I2C的验证学习 关于MPU6050寄存器相关可以参考https blog csdn net he yuan article details 76559569 I2C时序很多 xff0c 我是直接以原子I2C的程
  • String的长度限制

    String的长度 是有限制的 String存储 String其实是使用的一个char类型的数组来存储字符串中的字符的 看看字符串返回长度的方法 返回值类型是int类型 其长度最大限制为2 31 1 xff0c 那么说明了数组的长度是0 2
  • 通过isapi协议抓拍图片

    PC端通过isapi协议抓拍摄像头图片 说明 xff1a 1 isapi协议类似于http协议 2 通过isapi协议抓拍图片要经过这几个步骤 2 1 先创建socket xff0c 再连接服务器 xff08 也就是摄像机 xff09 co
  • yolo|使输出的结果txt含目标的四个坐标信息及类别置信度

    最近参加的智能船舶挑战赛对结果的格式要求 xff1a 包含目标边界框从左上角开始的顺时针标注点坐标 xff0c 目标类别以及目标类别分数 xff0c 并用空格分开 如下图所示 xff1a 故对yolov5的detect py进行修改 xff
  • 平台开发——安装海康摄像头(2402系列球机)并实现对其RTSP的推流

    本次购入了一台海康2402系列球机 xff08 DS 2DC2402IW D3 W xff09 xff0c 对设备进行了激活 设置及简要操作 xff0c 在服务器上对其进行了推流 购买摄像头 本次购买了海康威视DS 2DC2402IW D3
  • TIPS:Ubuntu 系统python版本切换

    1 查看 xff08 1 xff09 查看系统中存在的python版本 xff1a ls usr bin python xff08 2 xff09 查看系统默认版本 xff1a python version 2 修改 xff08 1 xff
  • 报错:CommandNotFoundError: Your shell has not been properly configured to use ‘conda activate‘.

    新安装anaconda xff0c 输入 conda activate 报错 终端输入 xff1a source activate source deactivate conda activate
  • Windows下C++调用Http接口

    1 WininetHttp h span class token macro property span class token directive keyword pragma span once span span class toke
  • ubuntu系统 PyImport_ImportModule 返回 NULL

    原因 xff1a 1 python文件出错 2 python文件路径出错 在PyImport ImportModule命令前添加语句 PyRun SimpleString 34 import sys 34 PyRun SimpleStrin
  • ModuleNotFoundError:No module named

    经典报错 xff1a ModuleNotFoundError No module named XXX 但通过conda list 可以发现相关第三方包 在程序中添加路径 import sys sys path append 39 三方包路径
  • Iterator迭代器

    1 迭代器的概述 迭代器 是一种通用的遍历集合 取出集合中元素的方式 迭代器由来 集合有很多种 每种集合的数据结构是不同的 数组 链表 哈希表 集合取出元素的方式也不同 我们不可能为每种集合都定义一种取出元素的方式 浪费 所以我们就可以使用