2010-01-25 25 views

Respuesta

26

Puede extender Iterator, lo que requerirá que implemente las next y hasNext métodos:

class MyAnswer extends Iterator[Int] { 
    def hasNext = true 
    def next = 42 
    } 

Pero, obtendrá una mayor flexibilidad si se amplía Iterable, que requiere implementar elements (o iterator en 2,8):

class MyAnswer extends Iterable[Int] { 
    def iterator = new Iterator[Int] { 
     def hasNext = true 
     def next = 42 
    } 
    } 

un idioma común parece ser para exponer un iterador a alguna colección privada, así:

class MyStooges extends Iterable[String] { 
    private val stooges = List("Moe", "Larry", "Curly") 
    def iterator = stooges.iterator 
    } 
+0

No hay forma de enviar mensajes privados, pero me gustaría plantear una pregunta: ¿podría indicarme un uso del idioma común que menciona? Si no, ¿para qué podría ser útil? ¿Por qué no solo devuelve la lista? ¿No sería este idioma menos eficiente? (También: he visto ese "truco" Iterable [A] varias veces y parece ser una de las formas más rápidas de crear algo parecido a una colección, ¿hay alguna "alternativa" a este enfoque? Lo hago porque Iterator da poca información para que los métodos no puedan optimizarse bien, ¿y si supiera que mi pseudo coll regresa ordenado o tiene acceso aleatorio rápido? – Aktau

7

Para un método, simplemente yield:

def odd(from: Int, to: Int): List[Int] = 
    for (i <- List.range(from, to) if i % 2 == 1) yield i 
+4

Correcto, pero ... el ejemplo del código en realidad no responde la pregunta. ¡Simplemente reemplace ambas instancias de "Lista" con "Iterador" y funciona perfectamente! –

0

Estas dos respuestas tenían la ayuda de los puestos de abajo y gracias @Dima.

supongamos que tiene una lista de clase vinculado. Y el requisito es imprimir todos los elementos en la lista.

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 =() 

Ahora permite implementar el iterador en esta clase.

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 

En la implementación del iterador, una vez que ptr llegó al final, no pudo avanzar. La implementación Iterable resuelve esto.

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 
Cuestiones relacionadas