集合中的几种遍历方法

前序:使用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);
            }
        );

相关推荐
鬼火儿4 小时前
SpringBoot】Spring Boot 项目的打包配置
java·后端
cr7xin4 小时前
缓存三大问题及解决方案
redis·后端·缓存
间彧5 小时前
Kubernetes的Pod与Docker Compose中的服务在概念上有何异同?
后端
间彧6 小时前
从开发到生产,如何将Docker Compose项目平滑迁移到Kubernetes?
后端
间彧6 小时前
如何结合CI/CD流水线自动选择正确的Docker Compose配置?
后端
间彧6 小时前
在多环境(开发、测试、生产)下,如何管理不同的Docker Compose配置?
后端
间彧6 小时前
如何为Docker Compose中的服务配置健康检查,确保服务真正可用?
后端
间彧6 小时前
Docker Compose和Kubernetes在编排服务时有哪些核心区别?
后端
间彧6 小时前
如何在实际项目中集成Arthas Tunnel Server实现Kubernetes集群的远程诊断?
后端
brzhang6 小时前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构