我曾经使用IteratorsScala中的Regexes,但我并不理解它的兴趣.
我知道它有一个状态,如果我在它上面调用next()方法,它每次都会输出不同的结果,但是我没有看到任何可以用它做的事情,而这是不可能的Iterable.
并且它似乎不像Akka Streams(例如)那样工作,因为以下示例直接打印所有数字(没有等待我想象的一秒):
lazy val a = Iterator({Thread.sleep(1000); 1}, {Thread.sleep(1000); 2}, {Thread.sleep(1000); 3})
while(a.hasNext){ println(a.next()) }
Run Code Online (Sandbox Code Playgroud)
那么使用的目的是Iterators什么?
也许,迭代器最有用的特性是它们很懒惰.考虑这样的事情:
(1 to 10000)
.map { x => x * x }
.map { _.toString }
.find { _ == "4" }
Run Code Online (Sandbox Code Playgroud)
此片段将平方10000个数字,然后生成10000个字符串,然后返回第二个.这另一方面:
(1 to 10000)
.iterator
.map { x => x * x }
.map { _.toString }
.find { _ == "4" }
Run Code Online (Sandbox Code Playgroud)
...只计算两个正方形,并生成两个字符串.
当您需要包装一些设计不佳的(java?)对象以便能够以函数样式处理它们时,迭代器通常也很有用:
val rs: ResultSet = jdbcQuery.executeQuery()
new Iterator {
def next = rs
def hasNext = rs.next
}.map { rs =>
fetchData(rs)
}
Run Code Online (Sandbox Code Playgroud)
流类似于迭代器 - 它们也是惰性的,也可用于包装:
Stream.continually(rs).takeWhile { _.next }.map(fetchData)
Run Code Online (Sandbox Code Playgroud)
但主要区别在于流记住了实现的数据,因此您可以多次遍历它们.这很方便,但如果原始数据量非常大,可能会很昂贵,特别是如果它被过滤到更小的尺寸:
Source
.fromFile("huge_file.txt")
.getLines
.filter(_ == "")
.toList
Run Code Online (Sandbox Code Playgroud)
这仅大致(忽略缓冲,对象开销和其他特定于实现的细节),内存量,将一行保留在内存中,加上文件中有许多空行.
这另一方面:
val reader = new FileReader("huge_file.txt")
Stream
.continually(reader.readLine)
.takeWhile(_ != null)
.filter(_ == "")
.toList
Run Code Online (Sandbox Code Playgroud)
...将最终得到内存中的全部内容huge_file.txt.
最后,如果我正确理解了您的示例的意图,那么您可以使用迭代器来完成它:
val iterator = Seq(1,2,3).iterator.map { n => Thread.sleep(1000); n }
iterator.foreach(println)
// Or while(iterator.hasNext) { println(iterator.next) } as you had it.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
178 次 |
| 最近记录: |