集合中的几种遍历方法

前序:使用Collection集合,来完成下面的代码实现。

值得注意的是

arduino 复制代码
Collection 是一个接口,我们不能直接new它的对象,小编技术有限,只能
           创建它实现类的对象。
           以下是Collection的实现类:ArrayList   LinkedList  Vector(以过时)。

话不多说,进入操作。

首先我们创建一个集合对象

csharp 复制代码
Collection<String>coll=new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");

一.使用增强for循环遍历集合

markdown 复制代码
先给出增强的格式:
for(元素的数据类型 变量名: 数组  集合){

     }
细节: s其实是一个第三方类型,在循环过程中依次表示集合中的每一个数据 修改 s这个变量,不会改变集合原本的数据
csharp 复制代码
Collection<String>coll=new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");

 for(String s:coll){
            System.out.println(s);
        }

代码执行结果如下:

二.使用迭代器进行遍历


迭代器可以抽象认识为c语言中的指针一环节:通过遍历迭代器的对象,依次移动,判断指向的位置是否有对象,如果有获取并进行下一次移动,没有,则停止。

所以,迭代器的书写格式可以分成下面三个部分

vbnet 复制代码
Iterator<E>  iterator()   :获取一个迭代器对象
boolean hasNext()  : 判断当前指向的位置是否有元素
E next()  :   获取当前指向的元素并移动指针

1.依旧先创建一个集合,并添加数据。

csharp 复制代码
Collection<String>coll=new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");

2.创建迭代器对象(it): Iterator it=coll.iterator();

rust 复制代码
        //2.获取迭代器对象
        Iterator<String> it = coll.iterator();
        //3.遍历
        while(it.hasNext() ){
            String str = it.next();
            System.out.print(str+" ");

输出即可。

注意:在使用迭代器中,我们往往会出现一些小毛病。

如:出现了一种越界情况。为什么呢?

arduino 复制代码
仔细观察截图的代码可以发现:在遍历过程中,我们通过集合coll,调用了集合中remove(删除元素)的方法,将它撤去,发现代码又能继续运行了。原来就是这行代码出了问题。

造成的原因:

1,比如str指针指向集合的第2个元素,但还没有读,但你将当前指针前面的删除了,从删除位置起的所有元素都会往前移-个,这时就造成你原来指针指向的还没读的元素往前移了,你再用迭代器获取就获取不到了。

2,如果你删除的是记录当前指针位置后面的元素不会有影响,因为删除后面的,后面的元素往前移,但你指针当前的元素没有移动,所以就不会少读,所以说你只要删除的是指针后面的元素就不会有影响,但为了保证万无一失,源码编写者就不允许你遍历时便便删除。

但如果我们就是要删除在迭代器中集合的元素呢?这好办,集合方法不行,我就用迭代器的啊!

其实,迭代器的设计早已经考虑了这种情况: 他给你提供迭代器的删除方法,有规律的删除,他在有规律的移动,他的方案就是:可以删除你当前遍历的元素,再将指针向前移动一位,并目只循序你调用一次选代器的remove,这样就解决了你遍历时自己调用集合remoye任意删造成少适的情况)

但用了迭代器的方法就一定对吗?答案不一定。

我们又看上面的修正代码,不是已经使用了迭代器删除的方法了吗?怎么还是错!不要急

仔细看。我们在最后一行中,又再次调用it.next的方法。噢噢。问题就是这里了。

其实这里的问题和上面的类似,也是使得指针异常了:

因为迭代器时,指针是不会复位的,当你再调用next时,指针指向着上一次集合的末尾。末尾后面是什么,是无尽的空白啊。你现在再去访问,当然访问不到啊。所以我们心爱的idea就提示了我们--NoSuchElementException,预期值不存在。

那怎么解决呢?

再new一次迭代器对象,再来一遍就行了,对,没错,就是这么简单!

三.Lambda表达式遍历:

如果不熟悉Lambda表达式的话,可以参考顶部的Lambda代码介绍:

创建集合添加数据的代码就不写了,直接上关键代码!

先创建匿名内部类来实现遍历。

typescript 复制代码
coll.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

再改写成Lambda来遍历,如下代码

ini 复制代码
 coll.forEach((s)-> {
            System.out.println(s);
            }
        );

相关推荐
喵手11 分钟前
如何利用Java的Stream API提高代码的简洁度和效率?
java·后端·java ee
掘金码甲哥17 分钟前
全网最全的跨域资源共享CORS方案分析
后端
m0_4805026424 分钟前
Rust 入门 生命周期-next2 (十九)
开发语言·后端·rust
张醒言31 分钟前
Protocol Buffers 中 optional 关键字的发展史
后端·rpc·protobuf
鹿鹿的布丁1 小时前
通过Lua脚本多个网关循环外呼
后端
墨子白1 小时前
application.yml 文件必须配置哇
后端
xcya1 小时前
Java ReentrantLock 核心用法
后端
用户466537015051 小时前
如何在 IntelliJ IDEA 中可视化压缩提交到生产分支
后端·github
小楓12011 小时前
MySQL數據庫開發教學(一) 基本架構
数据库·后端·mysql
天天摸鱼的java工程师1 小时前
Java 解析 JSON 文件:八年老开发的实战总结(从业务到代码)
java·后端·面试