8

前言

在一次写一个返回数据库中未批改的作业的功能时,偶然接触到了迭代器的概念。从仓库层获取所有作业,我想通过遍历查找每个作业Reviewed字段是否为false,如果为false,则遍历停止,返回该作业。但是如何从所有作业中一个一个获取作业呢。

迭代器的使用

我们获取一个表中的所有字段是调用的仓库层的findAll()方法,

Iterable<T> findAll();

我发现他放回的是Iterable<T>类型,我就去查了Iterable的意思,译为可迭代的。然后就去网上找Iterable容器使用方法。
下面说明一下它的使用
1.使用方法iterator()要求容器返回一个Iterator。我们现在接收到的是可迭代的容器,使用iterator()方法变成迭代器。

Iterable<Work> works = workRepository.findAll();

Iterator iter = works.iterator()

现在我们就获得了一个迭代器。
2.使用next()获得序列中的下一个元素。第一次调用Iterator的next()方法时,它返回序列的第一个元素。

Work nextWork = (Work)iter.next();

3.使用hasNext()检查序列中是否还有元素。这样我们就可以在for循环中加以判断。

Iterable<Work> works = workRepository.findAll();
    for (Iterator iter = works.iterator(); iter.hasNext();) {
        Work nextWork = (Work)iter.next();
        if (nextWork.getReviewed() == false) {
            return nextWork;
        }
    }
    return null;
}

最后代码,构造一个for循环,不断地判断下一个作业是否批阅过。用hasNext方法判断迭代器是否到头了。
4.使用remove()将迭代器新返回的元素删除。这里我们没有用到,这个方法而不常用。

迭代器

迭代器是一种设计模式,同时他也是一个对象,下面是他的部分源码,我们可以看到他的三个方法。

public interface Iterator<E> {
    boolean hasNext();

    E next();

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
}

迭代器就像一辆火车,我们只能从车头走向第二列车厢,从第二列车厢走向下一列车厢,而不能从车头直接调到车尾。
我们只能访问他的下一个元素,这跟我们的数组有所区别。因此,迭代器适合访问链式结构。同时,它还可以访问没有顺序的集合。

改进

回到我们情景本身,其实JPA为我们准备了更好的方法。

/**
 * 获取一个未批改的作业
 * @return 若有,返回一个作业,若没有,返回null
 */
Work findTopByReviewedIsFalse();

仓库层加入此方法,m层直接调用这个方法,才是最优的解。

总结

迭代器作为一种设计模式,我们无须考虑遍历序列的底层结构,只要拿到这个对象,使用迭代器就可以遍历这个对象的内部。这使得我们的遍历与被遍历对象分离。

参考

迭代器的使用
Java迭代器


小强Zzz
1.2k 声望32 粉丝