迭代器的使用 -- 《JAVA编程思想》33

本文介绍了Java中迭代器(Iterator)的基本概念及其使用方法,包括遍历集合、移除元素等操作,并对比了Iterator与ListIterator的区别。此外,还探讨了foreach循环在集合遍历中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

任何容器类,都可以通过某种方式插入、添加或者移除元素。例如:List 通过 add() 方法添加元素,get() 方法获取元素,remove() 方法移除元素。

但往更上层的角度思考,就好发现一个缺点:有时候我们希望针对 List 的方法,对于 Set 也可以生效,我们不需要关心容器的具体类型的前提下,对容器进行一些通用的操作。

迭代器由此应运而生,迭代器 Iterator 用来遍历并选择序列中的对象,它是一个轻量级对象,创建的代价也极小。

Iterator 主要有以下4类用途:

(1)容器类通过调用 iterator() 方法返回一个 Iterator 对象,Iterator 将准备好返回序列的第一个元素。

(2)Iterator 调用 next() 方法获取序列中的下一个元素。

(3)Iterator 调用 hashNext() 检查序列中是否还有元素。

(4)Iterator 使用 remove() 将迭代器最新的一个返回元素删除。

下面我们看看迭代器具体如何使用。

首先,定义一个工具类 Fruits 用来返回指定长度的集合。

public class Fruits {

    public static String[] fruits = {"apple", "orange", "banana", "lemon", "watermelon", "cheery", "pear", "peach",
            "strawberry", "mongo"};


    public static class Fruit {

        private int id;

        private String name;

        public Fruit(int id, String name) {
            this.id = id;
            this.name = name;
        }

        public int getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "Fruit{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    public static List<Fruit> arrayList(int size) {
        if (size < 1) {
            return new ArrayList();
        }
        if (size > fruits.length) {
            size = fruits.length;
        }
        List<Fruit> list = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            Fruit fruit = new Fruit(i + 1, fruits[i]);
            list.add(fruit);
        }
        return list;

    }

}

接下来尝试调用迭代器内的各种方法,查看输出结果。

public class SimpleIteration {

    public static void main(String[] args) {
        ArrayList<Fruits.Fruit> fruitList = Fruits.arrayList(10);
        Iterator<Fruits.Fruit> iterator = fruitList.iterator();
        //判断迭代器是否还有元素
        while (iterator.hasNext()){
            //获取下一个元素
            System.out.println(iterator.next());
        }
        //重新获取迭代器,移除前5个元素
        System.out.println("开始移除元素");
        iterator = fruitList.iterator();
        for (int i = 0; i < 5; i++) {
            iterator.next();
            iterator.remove();
        }
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

}
Fruit{id=1, name='apple'}
Fruit{id=2, name='orange'}
Fruit{id=3, name='banana'}
Fruit{id=4, name='lemon'}
Fruit{id=5, name='watermelon'}
Fruit{id=6, name='cheery'}
Fruit{id=7, name='pear'}
Fruit{id=8, name='peach'}
Fruit{id=9, name='strawberry'}
Fruit{id=10, name='mongo'}
开始移除元素
Fruit{id=6, name='cheery'}
Fruit{id=7, name='pear'}
Fruit{id=8, name='peach'}
Fruit{id=9, name='strawberry'}
Fruit{id=10, name='mongo'}

不过我们发现 Iterator 只支持元素的向前移动,但其还有一个功能更为强大的子类 ListIterator:

(1)容器类的 listIterator() 可以从指定起始位置后开始返回元素

(2)迭代器的 nextIndex() 获取后一个元素的索引

(3)迭代器的 previousIndex() 获取前一个元素的索引

(4)迭代器的 set() 可覆盖当前元素

public class SimpleIteration {

    public static void main(String[] args) {
        ArrayList<Fruits.Fruit> fruitList = Fruits.arrayList(10);
        ListIterator<Fruits.Fruit> fruitListIterator = fruitList.listIterator(5);
        //重新获取迭代器
        while (fruitListIterator.hasNext()) {
            System.out.print("\t" + fruitListIterator.previousIndex());
            System.out.print("\t" + fruitListIterator.nextIndex());
            System.out.print("\t" + fruitListIterator.next());
            fruitListIterator.set(new Fruits.Fruit(0,"grape"));
            System.out.println();
        }
        System.out.println(fruitList);
    }
    
}
	4	5	Fruit{id=6, name='cheery'}
	5	6	Fruit{id=7, name='pear'}
	6	7	Fruit{id=8, name='peach'}
	7	8	Fruit{id=9, name='strawberry'}
	8	9	Fruit{id=10, name='mongo'}
[Fruit{id=1, name='apple'}, Fruit{id=2, name='orange'}, Fruit{id=3, name='banana'}, Fruit{id=4, name='lemon'}, Fruit{id=5, name='watermelon'}, Fruit{id=0, name='grape'}, Fruit{id=0, name='grape'}, Fruit{id=0, name='grape'}, Fruit{id=0, name='grape'}, Fruit{id=0, name='grape'}]

最后需要补充的是,foreach 也可以用于遍历各种集合类,只要是实现了 Iterable 接口的类,都可以用于 foreach 之中(foreach 支持遍历数组,但数组并未实现 Iterable 接口)。

public class SimpleIteration {

    public static void main(String[] args) {
        ArrayList<Fruits.Fruit> fruitList = Fruits.arrayList(10);
        for (Fruits.Fruit fruit : fruitList) {
            System.out.println(fruit);
        }
    }

}
Fruit{id=1, name='apple'}
Fruit{id=2, name='orange'}
Fruit{id=3, name='banana'}
Fruit{id=4, name='lemon'}
Fruit{id=5, name='watermelon'}
Fruit{id=6, name='cheery'}
Fruit{id=7, name='pear'}
Fruit{id=8, name='peach'}
Fruit{id=9, name='strawberry'}
Fruit{id=10, name='mongo'}

所有 Collection 类都默认实现了 Iterable 接口。
在这里插入图片描述
下面我们自己尝试实现一个 Iterable 接口,用于 foreach 循环。

public class IterableClass implements Iterable<String> {

    protected String[] words = ("Do you know she has a brother ?").split(" ");

    @Override
    public Iterator<String> iterator() {


        return new Iterator<String>() {

            private int index = 0;

            @Override
            public boolean hasNext() {
                return index < words.length;
            }

            @Override
            public String next() {
                return words[index++];
            }

        };
    }

    public static void main(String[] args) {
        IterableClass iterableClass = new IterableClass();
        for (String word : iterableClass) {
            System.out.println(word);
        }
    }


}
Do
you
know
she
has
a
brother
?

本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。

若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BaymaxCS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值