2010-01-25 77 views

回答

26

可以扩展Iterator,这将要求您实现nexthasNext方法:

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 
    } 
+0

有没有办法发送私人消息,但我想提出一个问题:你可能指出我使用你提到的常见成语吗?如果不是,那对它有什么用处?为什么不只是返回列表?这个成语不会更低效吗? (另外:我已经看到Iterable [A]“欺骗”了几次,它似乎是创建集合的最快方法之一,这种方法有没有“替代品”?I aks因为Iterator给出了很少的信息,所以方法不能很好地优化,如果我知道我的伪科尔返回有序或具有快速随机访问)怎么办? – Aktau 2012-02-21 10:45:38

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帮助。

让我们假设你有一个类链表。而要求是打印列表中的所有元素。

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