def filter(p: A => Boolean): Iterator[A] = new AbstractIterator[A] {
// TODO 2.12 - Make a full-fledged FilterImpl that will reverse sense of p
private var hd: A = _ //迭代器当前游标所在的值
private var hdDefined: Boolean = false
def hasNext: Boolean = hdDefined || {
do {
if (!self.hasNext) return false
hd = self.next()
} while (!p(hd))
hdDefined = true
true
}
def next() = if (hasNext) { hdDefined = false; hd } else empty.next()
}
filter为scala trait Iterator 内的一个方法,主要目的是在原迭代器基础上根据p匿名函数生成一个符合条件的迭代器
符合什么条件呢?即原 Iterator 的元素迭代一遍,并作为 p 匿名函数的参数执行一遍,凡是结果为 true 的元素则满足条件,放入新的迭代器中
private var hd: A = _ 这个可以看作迭代器在迭代的时候当前游标所指向的元素值
private var hdDefined: Boolean = false 这个可以看作一个标识符,迭代器找到了符合条件的元素,该开关置为true,否则置为false
后续也是根据这个值来实现 hasNext方法
hasNext方法也是作为判断是否还存在满足条件元素的依据
hasNext方法内部会先去判断hdDefined的值,
- 如果该值为true,则直接判定还有满足条件的元素(这么看来,hdDefined有点缓存的味道,如果没有这个值,多次调用hasNext方法则必然需要重复执行迭代器的循环,使性能降低)
- 如果该值为false,则再执行迭代器循环,其中 self.hasNext 、self.next() 都是外部迭代器的方法,当找到一个符合条件的元素后 (!p(hd)) ,执行p函数结果为true,取反后为false,跳出循环。同时将hdDefined置为true,表示已找到了下一个满足条件的元素。同时hasNext方法也返回true
next方法用来获取下一个满足条件的元素
首先调用hasNext 查看是否有满足条件的元素,没有则直接抛出Nothing
有则返回该元素,同时将hdDefined置为false,表示已找到这个符合条件的元素,需要重新循环才能判断是否存在下一个满足条件的值
短短几行代码,其中却蕴含了巨大的智慧和设计诀窍
网友评论