JavaSE学习——迭代器

java 复制代码
        List<String> list1 = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        for(String s : list1){
            System.out.println(s);
        }

迭代器相当于一种遍历的方式,专门用来遍历集合的工具。

三个核心方法:hasNext()判断是否存在下一个元素;next()返回下一个元素,remove删除刚遍历的那个元素。

比如下面的代码构建一个迭代器,用来遍历集合的元素:

java 复制代码
public class Main {
    public static void main(String[] args){
        List<String> list1 = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        Iterator<String> iterator = list1.iterator();
        while(iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }
    }
}

迭代器只能用一次,比如:

java 复制代码
        List<String> list1 = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        Iterator<String> iterator = list1.iterator();
        while(iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }
        while(iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }

现在使用迭代器的remove方法,迭代之后进行删除:

java 复制代码
        List<String> list1 = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        Iterator<String> iterator = list1.iterator();
        while(iterator.hasNext()){
            String next = iterator.next();
            iterator.remove();
            System.out.println(next);
        }
        System.out.println(list1);

forEachRemaining()方法也可以进行遍历,传入的是一个consumer,有str就可以进行消费:(比如下面的例子就是进行一个打印输出)。

java 复制代码
        List<String> list1 = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        Iterator<String> iterator = list1.iterator();
        iterator.forEachRemaining(str->{
            System.out.println(str);
        });
        System.out.println(list1);

那回到我们最初的一个语法糖,它的底层就是迭代器:

for(String s : list1){

System.out.println(s);

}


比如现在还想打印一下下标:

java 复制代码
        List<String> list = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        int index = 0;
        for(String s: list){
            System.out.println(s+"位于"+index);
            index++;
        }

下面的代码也可以:(注意看index的定义位置)

java 复制代码
public class Main {
    static int index = 0;
    public static void main(String[] args){
        List<String> list = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));

        list.forEach(str->{
            System.out.println(str+"下标是:"+index);
            index++;
        });
    }
}

在lambda表达式里面不可以对局部变量进行一个改变,但是可以该表全局变量。下面的代码就是不可以的:

java 复制代码
public class Main {
    
    public static void main(String[] args){
        List<String> list = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        int index = 0;
        list.forEach(str->{
            System.out.println(str+"下标是:"+index);
            index++;
        });
    }
}

下面简单看一下顶层的接口父类 Iterable

创建了一个迭代器:

java 复制代码
Iterator<T> iterator();

默认实现了forEach()方法:

java 复制代码
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

此外,还有listIterator方法,是列表专用的迭代器方法,只要是列表都可以进行调用。相当于为列表专门强化了一遍迭代器。

java 复制代码
        List<String> list = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        ListIterator<String> stringListIterator = list.listIterator();

得到的对象可以调用更多的迭代器方法:

复制代码
比如previous()方法可以得到前一个元素,previousIndex()方法可以得到前一个元素的下标等等,还可以add()方法进行边遍历边添加。
java 复制代码
        List<String> list = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        ListIterator<String> stringListIterator = list.listIterator();
        while(stringListIterator.hasNext()){
            int i = stringListIterator.nextIndex();
            String next = stringListIterator.next();
            System.out.println("当前元素: "+next+", 位置: " + i);
        }

现在使用add()方法:

java 复制代码
        while(stringListIterator.hasNext()){
            int i = stringListIterator.nextIndex();
            String next = stringListIterator.next();
            stringListIterator.add("1314");
            System.out.println("当前元素: "+next+", 位置: " + i);
        }

现在我们知道,上面的迭代器代码运行完之后,迭代器的指针指向了最后一个元素,因为加强后的listIterator还可以验证前面的元素是否存在,所以可以向前遍历:

java 复制代码
        while(stringListIterator.hasNext()){
            int i = stringListIterator.nextIndex();
            String next = stringListIterator.next();
            stringListIterator.add("1314");
            System.out.println("当前元素: "+next+", 位置: " + i);
        }
        while (stringListIterator.hasPrevious()){
            int i = stringListIterator.previousIndex();
            String pre = stringListIterator.previous();
            System.out.println("当前元素:" + pre + "下标是:" + i);
        }

当然,因为这个迭代器是可以双向使用的,所以可以不止使用一次


有add()方法,也有remove()方法。注意,虽然可以一边遍历,一边添加/移除,但是迭代器依然遍历的指针指向原始的元素,不会把新添加的元素给遍历掉。

之所以要使用迭代器进行一边遍历一边添加/删除。但是在语法糖里面不行,会报错。下面的代码是错的:

java 复制代码
        List<String> list = new LinkedList<>(Arrays.asList("lhw", "hxl", "520"));
        for(String s : list){
            list.add("");
        }
相关推荐
蹊黎2 小时前
C++中vector类的部分简单实现
开发语言·c++·visual studio
qq_284274052 小时前
机械设计基础·滚动轴承全解(类型·代号·选型·寿命)+轮系与蜗杆蜗轮传动
笔记·学习·自动化·制造
驭渊的小故事2 小时前
MyBatis XML 开发实战:从配置到 CRUD 全解析
xml·java·mybatis
哦虎!7 小时前
【JavaEE】网络初识
java
2603_965148117 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
for_ever_love__7 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
程序猿追8 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓8 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播8 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
欣栀♡8 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm