为了能够从方法/类中返回Iterator,我必须做些什么?如何将这种特质添加到课堂上?你如何在Scala中返回迭代器?
19
A
回答
26
可以扩展Iterator,这将要求您实现next
和hasNext
方法:
class MyAnswer extends Iterator[Int] {
def hasNext = true
def next = 42
}
但是,如果你扩展Iterable,这就需要你在2.8实现elements
(或iterator
你会得到更多的灵活性):
class MyAnswer extends Iterable[Int] {
def iterator = new Iterator[Int] {
def hasNext = true
def next = 42
}
}
一个常见的成语似乎是一个迭代器暴露于一些私人收藏,像这样:
class MyStooges extends Iterable[String] {
private val stooges = List("Moe", "Larry", "Curly")
def iterator = stooges.iterator
}
7
一种方法,只是yield:
def odd(from: Int, to: Int): List[Int] =
for (i <- List.range(from, to) if i % 2 == 1) yield i
+4
正确,但是...代码示例并没有真正回答这个问题。只需将“List”的两个实例都替换为“Iterator”,它就可以完美实现! – 2015-01-04 06:52:30
0
这两个答案必须从下面的帖子,感谢@Dima帮助。
How do I implement an iterator for an existing singly linked list?
why does this iterable implementation produce a stackoverflow?
让我们假设你有一个类链表。而要求是打印列表中的所有元素。
trait LinkedList {
def nodeValue: Int
def tailList: LinkedList
}
class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList
object Nil extends LinkedList {
def nodeValue = throw new IllegalAccessException("head of Nil")
def tailList = throw new IllegalAccessException("tail of Nil")
}
val singleLinkedList = new Node(1,Nil)
val chainedLinkedList = new Node(2,singleLinkedList)
print(chainedLinkedList)
[email protected]: Unit =()
现在让我们为这个类实现迭代器。
trait LinkedList extends Iterator[Int]{
def nodeValue: Int
def tailList: LinkedList
}
class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList {
var ptr: LinkedList = this
//The following two are mandatory for extending Iterator
override def hasNext: Boolean = ptr match { case Nil => false; case _=> true}
override def next(): Int = {
val result = ptr.nodeValue
ptr = ptr.tailList
result
}
}
object Nil extends LinkedList {
def nodeValue = throw new IllegalAccessException("head of Nil")
def tailList = throw new IllegalAccessException("tail of Nil")
//The following two are mandatory for extending Iterator
override def hasNext: Boolean = false
override def next(): Int = throw new IllegalAccessException("next of Nil")
}
val singleLinkedList = new Node(1,Nil)
val chainedLinkedList = new Node(2,singleLinkedList)
//Printing this first Time
chainedLinkedList.foreach(println)
//Prints 2 1
//Printing second Time
chainedLinkedList.foreach(println)
//No output
在迭代器实现中,一旦ptr达到最后,它可能不会前移。 Iterable实现解决了这个问题。
trait LinkedList extends Iterable[Int]{
val nodeValue: Int
val tailList: LinkedList
override def toString(): String = this.mkString(" -> ")
}
class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList {
override def iterator: Iterator[Int] = Iterator
.iterate(this: LinkedList)(_.tailList)
.takeWhile(_ != Nil)
.map(_.nodeValue)
}
object Nil extends LinkedList {
lazy val nodeValue= throw new IllegalAccessException("head of Nil")
lazy val tailList = throw new IllegalAccessException("tail of Nil")
override def iterator: Iterator[Int] = Iterator.empty
}
val singleLinkedList = new Node(1,Nil)
val chainedLinkedList = new Node(2,singleLinkedList)
//Printing this first Time
chainedLinkedList.foreach(println)
Output 2 -> 1
chainedLinkedList.foreach(println)
Output 2 -> 1
有没有办法发送私人消息,但我想提出一个问题:你可能指出我使用你提到的常见成语吗?如果不是,那对它有什么用处?为什么不只是返回列表?这个成语不会更低效吗? (另外:我已经看到Iterable [A]“欺骗”了几次,它似乎是创建集合的最快方法之一,这种方法有没有“替代品”?I aks因为Iterator给出了很少的信息,所以方法不能很好地优化,如果我知道我的伪科尔返回有序或具有快速随机访问)怎么办? – Aktau 2012-02-21 10:45:38