前言
在一次写一个返回数据库中未批改的作业的功能时,偶然接触到了迭代器的概念。从仓库层获取所有作业,我想通过遍历查找每个作业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层直接调用这个方法,才是最优的解。
总结
迭代器作为一种设计模式,我们无须考虑遍历序列的底层结构,只要拿到这个对象,使用迭代器就可以遍历这个对象的内部。这使得我们的遍历与被遍历对象分离。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。