Foreach 那点事

foreach 背后

平常我们循环一个 List 大概有下面这三种方式:

传统 for 循环


for (int i = 0; i < list.size(); i++) {
}

用迭代器进行迭代遍历


Iterator itr = list.iterator();
while (itr.hasNext()) {
    itr.next();
}

增强 for 循环,也就是 foreach


for (String str : list) {
}

如果你用 idea 进行开发的话,用迭代器进行遍历的时候,它会提醒你可以换成 foreach 循环,这说明这两者是一样的。事实上 foreach 循环只是迭代器循环的一种简便形式而已。

在 jdk 源码中,我们可以看到有 Iterable 这么一个接口,顾名思义,就是可迭代的意思,再看这个接口的具体内容:


/**
 * Implementing this interface allows an object to be the target of
 * the "foreach" statement.
 *
 * @param <T> the type of elements returned by the iterator
 *
 * @since 1.5
 */
public interface Iterable<T> {

    Iterator<T> iterator();
}

注意注释中内容,实现这个接口,可以让一个类能够使用 foreach 形式进行迭代。然后再看看唯一的方法返回值 Iterator,顾名思义就是迭代器,再看看迭代器源码:


public interface Iterator<E> {

    // 是否有下一个元素
    boolean hasNext();

    // 获取下一个元素
    E next();

    // 删除当前元素
    void remove();
}

Iterator 迭代器只是一个接口,里面的相关操作还须要用户自己实现。

实现自己的可迭代的类

有了上面的基础,我们就可以实现一个最简单的 List


// 首先实现 Iterable 接口
public class IteratorDemo<T> implements Iterable<T> {

    private Object[] table;
    private int size;

    public IteratorDemo(int capacity) {
        table = new Object[capacity];
    }

    // 实现获取迭代器的方法
    @Override
    public Iterator<T> iterator() {
        return new Itr();
    }

    public boolean add(T t) {
        if (size == table.length) {
            return false;
        }
        table[size++] = t;
        return true;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    // 定义迭代器实现类
    class Itr implements Iterator<T> {
        private int cursor;

        @Override
        public boolean hasNext() {
            return cursor + 1 <= size;
        }

        @Override
        @SuppressWarnings("unchecked")
        public T next() {
            return (T) table[cursor++];
        }

        @Override
        public void remove() {
        }
    }

    public static void main(String[] args) {
        IteratorDemo<String> demo = new IteratorDemo<>(2);
        demo.add("hello");
        demo.add("world");
        for (String s : demo) {
            System.out.println(s);
        }
    }
}

控制台

hello
world

Process finished with exit code 0

作用

知道 Iterator 相关的内容,再去看 ArrayList、HashMap 等源码会轻松许多~

posted @ 2022-06-09 14:35  Tailife  阅读(27)  评论(0编辑  收藏  举报