通过迭代器删除容器中的元素

news2024/11/23 21:10:52

        通过之前的介绍我们知道通过迭代器来遍历单例集合的操作仍然需要借助于循环结构。而且我们知道在单例集合中调用iterator方法返回的Iterator对象中还有一个remove方法我们没有介绍,它的作用是删除容器中的元素。说道这里应该有人会发现一个很明显的问题,那就是在单例集合中我们不是就已经定义过一个remove方法了吗,为什么还要在迭代器中定义一个remove方法呢?这不是多此一举吗?

        为了解决这个问题,我们首先要解决一个问题——在单例集合中能否在循环结构中对元素进行增删操作。答案自然是不行的,那为为什么?接下来我们进入分析。

        首先创建一个单例集合容器list,这个容器用ArrayList容器类来进行实现,因此它的元素具有索引,我们可以通过索引对它的元素进行操作。显然,在我们通过for循环来遍历元素之前对容器llist中的元素进行增删操作是没有问题的,但是现在我们想在进行遍历的同时对容器中的元素进行增删操作。

        一、删除元素。

        如果我们在遍历元素的时候删除了元素中指定位置的元素会出现什么现象呢。我们用一个实例来进行说明。在下面的这个代码中,我们将a、b、c、d四个元素添加到了容器list中,在遍历其中的元素时我们打算删除索引为2的元素,也就时删除元素c,这个是我们期望得到的结果。但是从执行结果来看,我们同时删除了元素c和d,这是为什么呢?因为当我们第一次删除了索引为2的元素时,容器的大小就发生改变了,也就是list.size的值从4变成了3,这时在变化了的容器容器中,元素d向前移动了一个位置,它的索引变成了2,所以再执行循环结构,自然会将他删除。也就是说这个代码无法完成我们只删除元素c的需求。当然,要完成我们的需求可以对这个代码做出简单的修改,在执行删除的部分添加判断条件,将代码改为

        if(c.eauals(list.get(i)){

                list.remove(i);

          }

这样显然时能够达到我们的要求的,可是如果要删除多个元素,显然不会是一种有效的方法,因此这种写法也不可取。

package com.container.demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorRemoveTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for (int i = 0; i < list.size(); i++) {
            list.remove(2);//改变数据结果
            //list.add("dd");死循环
            System.out.println(list.get(i));
        }
    }
}

        二、增加元素

        既然删除元素不可以,那么相对的在通过循环来遍历容器中的元素的同时往容器中增加元素显然而也是不可以的 。不过我们自然不信邪,抱着尝试弄死系统的态度我们浅浅尝试以下如果非要在遍历元素的时候向容器中添加元素又会发生什么样的情况呢?我们仍然以list容器为例子,在遍历元素时我们在for循环中添加元素dd,代码展示如下。

        根据运行结果我们发现代码陷入了死循环,这是为什么呢?在我们看来这个代码应该不具备死循环的条件才对。那么真的不具备吗?其实当我们在for循环中添加元素的时候,容器的大小就已经发生改变了,也就是说每执行一次循环list.size()的值都会加一,那么用来进行判断是否进行循环的变量i的值增加一,list.size()的值也会增加一,所以i的值永远比list.size()的值小。循环条件一直满足,所以循环一直执行。

package com.container.demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorRemoveTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for (int i = 0; i < list.size(); i++) {
            //list.add("dd");死循环
            System.out.println(list.get(i));
        }
    }
}

 

         通过上面的介绍我们知道,通过普通的循环结构去遍历容器中的元素时是不能对容器中的元素进行删除操作的。那么如果我们想要在遍历元素的同时对元素进行删除操作可不可以呢?答案是可以。这里只需要我们采用迭代器来遍历元素中的元素就可以在遍历元素的同时对元素进行删除操作。能这样做的原因是用迭代器遍历元素的的时候设计元素索引的应用,而且判断循环是否执行的条件也与元素的索引无关。

        但是这里有两个注意的点,第一是在通过迭代器来遍历容器中的元素的时候不能重复调用next方法,因为next方法不仅会返回当前位置的元素,还会将指针移动到下一个元素的位置。如果多次调用next方法,极有可能会导致容器中的元素丢失,无法正常遍历容器中的元素。另一个需要注意的点是,通过迭代器迭代元素时是不能向容器中添加元素的,虽然这么写在编译时不会报错,但是运行时是不被允许的。

        此外,我们之前就说过增强for循环即for-each循环其实也算是迭代器,所以用它来遍历容器中的元素时也可以调用remove方法来对容器中的元素进行删除操作,但仍然不可以添加元素。

package com.container.demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorRemoveTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for (int i = 0; i < list.size(); i++) {
            //list.remove(2);改变数据结果
            //list.add("dd");死循环
            System.out.println(list.get(i));
        }
        System.out.println("_____________________________");
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            //不能在一个迭代器种多次调用next()。
            String value = iterator.next();
            if("c".equals(value)){
                iterator.remove();
            }
        }
        for(Iterator<String> it = list.iterator();it.hasNext(); ){
            String va = it.next();
            System.out.println(va);
            //list.add("ddd");//编译不报错,但运行会报错,在迭代器包括增强for循环中不能添加元素
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1862476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第28课 绘制原理图——绘制导线

概述 放置完元器件之后&#xff0c;接着就要用导线将元器件的管脚一个一个连起来了。 绘制导线的方法 点击快速工具条上的“线”命令&#xff0c;进入绘制导线的过程。 点击选择某个管脚或电源端口&#xff0c;作为导线的起始端。 再点击选择另一个管脚或电源端口&#xff0c…

MT6989(天玑9300)芯片性能参数_MTK联发科5G处理器

MT6989是联发科Dimensity旗舰系列的成员&#xff0c;旨在为旗舰5G智能手机供应商提供最先进的技术和性能。MT6989也是联发科目前最具创新和强大的5G智能手机芯片&#xff0c;具有领先的功耗效率&#xff0c;无与伦比的计算架构&#xff0c;有史以来最快和最稳定的5G调制解调器&…

动物常见图像的图像分类数据集

常见动物图像分类数据集 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1zZnCUZuNlX6MjuZImlDjTw?pwd03b9 提取码&#xff1a;03b9 数据集信息介绍&#xff1a; 文件夹 大象 中的图片数量: 1446 文件夹 松鼠 中的图片数量: 1862 文件夹 河马 中的图片数量:…

YOLOv8/v10项目使用教程

根据改好的YOLOv8.yaml改yolov10.yaml教程 打开ultralytics/cfg/models/v8路径&#xff0c;找到需要移植的yaml文件&#xff0c;从其中复制相关的模块。打开一个YOLOv10的yaml文件。 注释掉之前相应位置的模块&#xff0c;并粘贴上面复制的模块&#xff0c;完成。 其余使用步骤…

upload-labs第14关

upload-labs第14关 第十四关一、源代码分析代码审计 二、绕过分析a. 制作图片码首先需要一个照片&#xff0c;然后其次需要一个eval.php。 b.上传图片码上传成功 c.结合文件包含漏洞进行访问访问&#xff1a;http://192.168.1.110/upload-labs-master/include.php?filehttp://…

SNEC天合储能秀:全球首发多元场景一站式工商业储能融合解决方案

6月13日-15日&#xff0c;SNEC2024光伏与智慧能源展在上海隆重举行&#xff0c;来自全球95个国家和地区3000家国内外展商齐聚展会&#xff0c;5000行业专家共话产业发展。致力于成为全球光储智慧能源解决方案的领导者&#xff0c;天合光能&#xff08;展位号&#xff1a;7.2H-E…

LiveMedia视频汇聚平台的设备管理功能

LiveMedia视频汇聚平台的设备管理功能是实现视频资源有效管理和控制的关键组成部分。以下是设备管理功能的详细介绍&#xff1a; 设备接入与管理&#xff1a; 设备添加与编辑&#xff1a;平台支持添加、编辑与删除设备&#xff0c;可编辑的信息包括设备接入的协议类型、服务节…

ICASSP论文结构研究

MLCA-AVSR 基于多层交叉注意融合的视听语音识别 ABSTRACT 目标任务现状、目前研究现状(研究大方向、研究的欠缺)、本文方法、方法效果(排名、分数) 有一个Index Terms INTRODUCTION 目标任务的简单发展历程与发展现状&#xff0c;目前任务的难点&#xff0c;指出为什么会…

代码随想录-Day39

62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&…

Gradle学习-2 Groovy

1、Groovy基础语法 1.1、基本数据类型 Groovy支持数据类型&#xff1a;byte, short, int, long, float, double, char &#xff08;1&#xff09;创建一个Android Studio项目 &#xff08;2&#xff09;在根目录新建一个 leon.gradle&#xff0c;输入以下内容 leon.gradle…

Netty学习(二)——黏包半包、协议设计解析、聊天室

一、粘包与半包 1.1 粘包和半包复现 1、粘包复现&#xff1a; Server代码&#xff1a; public class ProblemServer {public static void main(String[] args) throws InterruptedException {new ServerBootstrap()//若是指定接收缓冲区大小&#xff1a;就会出现黏包、半包…

计算机基础知识——面向对象:封装+继承+多态整理

面向对象三大特性&#xff1a;封装、继承、多态。 1.封装 将一系列相关事物的共同的属性和行为提取出来&#xff0c;放到一个类中&#xff0c;同时隐藏对象的属性和实现细节&#xff0c;仅对外提供公共的访问方式。 【JavaBean类就可以看作是封装的完美案例。】 setter和get…

电磁兼容试验数据的单位转换 笔记

1. 单位dB 的介绍 分贝&#xff08;decibel&#xff0c;/dɛsɪ.bɛl/&#xff09;是量度两个相同单位之数量比例的计量单位&#xff0c;主要用于度量声音强度&#xff0c;常用dB表示。 分贝是较常用的计量单位。可表示为&#xff1a; 1. 表示功率量之比的一种单位&#xff0c…

作业6.20

1.已知网址www.hqyj.com截取出网址的每一个部分(要求&#xff0c;该网址不能存入文件中) 2.将配置桥接网络的过程整理成文档&#xff0c;发csdn 步骤i&#xff1a;在虚拟机设置中启用桥接模式 1. 打开VMware虚拟机软件。 2. 选择您想要配置的虚拟机&#xff0c;点击菜单栏中的“…

正版软件 | Copywhiz 6:革新您的文件复制、备份与管理体验

在数字化时代&#xff0c;文件管理的效率直接影响到我们的生产力。Copywhiz 6 最新版本&#xff0c;带来了前所未有的文件处理能力&#xff0c;让复制、备份和组织文件变得轻而易举。 智能选择&#xff0c;只复制更新内容 Copywhiz 6 的智能选择功能&#xff0c;让您只需几次点…

PDF编辑软件pdf转word工具Acrobat DC百度云盘分享

如大家所了解的&#xff0c;Adobe Acrobat DC是一款高级PDF文档编辑和管理软件&#xff0c;它整合了创建、编辑、共享和签署PDF文件的强大功能。这款软件为用户提供了一系列高效的工具&#xff0c;使得处理PDF文件变得异常简单&#xff0c;大幅提升办公效率。 Acrobat DC软件核…

【实用软件】Internet Download Manager(IDM6.41)下载及安装教程

​数据表明但是能够通过搭配下载的方式来使用IDM&#xff08;比如用迅雷离线下载&#xff0c;115离线&#xff0c;百度网盘等离线下载好的资源&#xff0c;然后结合HTTP协议的特性再用IDM下载&#xff09;能够达到事半功倍的效果。有目共睹的是IDM下载HTTP链接十分快&#xff0…

ctr/cvr预估之DeepFM模型

ctr/cvr预估之DeepFM模型 在数字营销的浪潮中&#xff0c;点击率&#xff08;CTR&#xff09;和转化率&#xff08;CVR&#xff09;预估已成为精准广告投放和个性化推荐系统的核心。随着深度学习技术的蓬勃发展&#xff0c;传统的机器学习方法&#xff0c;如逻辑回归和因子分解…

26.高级特性(上)

目录 一、不安全的Rust二、不安全的超能力2.1 概念2.2 解引用裸指针2.3 调用不安全的函数或方法2.3 创建不安全代码的安全抽象2.4 使用extern函数调用外部代码2.5 访问或修改可变静态变量2.6 实现不安全trait2.7 访问联合体中的字段 三、高级trait3.1 关联类型在trait定义中指定…

沙姆镜头标定与重建

沙姆定律&#xff08; Scheimpflug principle&#xff09;则可以保证测量平面的物体能够清晰成像&#xff0c; 因此能够起到调整景深区域位置的作用。Scheimpflug 镜头就是根据沙姆定律所设计的一种特殊的镜头&#xff0c;通过机械结构使镜头与相机本体发生一定程度的偏转&…