bufferediterator.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 195 行
SCALA
195 行
/* __ *\** ________ ___ / / ___ Scala API **** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **** /____/\___/_/ |_/____/_/ | | **** |/ **\* */// $Id: BufferedIterator.scala 12641 2007-08-22 16:01:57Z mcdirmid $package scalaimport Predef._/** Buffered iterators are iterators which allow to inspect the next * element without discarding it. * * @author Martin Odersky * @author SeanMcDirmid * @version 2.0, 16/04/2007 */trait BufferedIterator[+A] extends Iterator[A] { /** Checks what the next available element is. * * @return the current element */ def head : A def headOpt = if (!hasNext) None else Some(head) override def buffered: this.type = this /** iterates over and applies <code>f</code> to the next element * if this iterator has a next element that <code>f</code> is defined for. */ def readIf[T](f : PartialFunction[A,T]) : Option[T] = if (hasNext && f.isDefinedAt(head)) Some(f(next)) else None /** iterates over elements as long as <code>f</code> is true * for each element, returns whether anything was read */ def readWhile(f : A => Boolean) : Boolean = { var read = false while (hasNext && f(head)) { next read = true } read } def advanced : BufferedIterator.Advanced[A] = new BufferedIterator.Default[A] { protected def fill(sz : Int) : Seq[A] = if (BufferedIterator.this.hasNext) (BufferedIterator.this.next) :: Nil else Nil }}object BufferedIterator { import collection.mutable.{Buffer, ListBuffer} trait Advanced[+A] extends BufferedIterator[A] { /** returns the first <code>sz</code> elements that will be iterated by this iterator, * or fewer if the iterator has less elements left to iterate over */ def peekList(sz : Int) : Seq[A] /** Checks what the next available element is. * * @return the current element */ def head: A = peek(0) /** return the <code>n</code>th element that will be iterated by this iterator */ def peek(n : Int) : A = { val lst = peekList(n + 1); if (n == 0) { return if (lst.isEmpty) defaultPeek else lst(0) } val i = lst.elements var m = 0 while (m < n && i.hasNext) { i.next; m += 1 } if (!i.hasNext) defaultPeek else i.next } /** element returned when no element left to iterate over; * throws <code>NoSuchElementException</code> by default */ protected def defaultPeek : A = throw new Predef.NoSuchElementException /** true if elements of <code>seq</code> will be iterated over next in this iterator */ def startsWith(seq : Seq[Any]) : Boolean = { var sz = seq.length val j = peekList(sz).elements val i = seq.elements while (i.hasNext && j.hasNext) if (i.next != j.next) return false return !i.hasNext } def readIfStartsWith(seq : Seq[Any]) : Boolean = { if (startsWith(seq)) { var i = 0 while (i < seq.length) { next; i = i + 1 } true } else false } override def counted : CountedIterator[A] with Advanced[A] = new CountedIterator[A] with Advanced[A] { private var cnt = -1 def count = cnt override def hasNext: Boolean = Advanced.this.hasNext override def next: A = { cnt += 1; Advanced.this.next } override def peekList(sz : Int) : Seq[A] = Advanced.this.peekList(sz) override protected def defaultPeek : A = Advanced.this.defaultPeek override def counted : this.type = this } override def hasNext = !peekList(1).isEmpty override def toString = { val list = peekList(0) if (!list.isEmpty) "peek " + list else "***" } override def advanced : this.type = this } trait PutBack[+A] extends Advanced[A] { protected[this] def putBack(a : A) : Unit override def counted : CountedIterator[A] with PutBack[A] = new CountedIterator[A] with PutBack[A] { private var cnt = -1 def count = cnt override protected def defaultPeek : A = PutBack.this.defaultPeek override def next: A = { cnt += 1; PutBack.this.next } override def hasNext: Boolean = PutBack.this.hasNext override def peekList(sz : Int) : Seq[A] = PutBack.this.peekList(sz) override protected[this] def putBack(a : A) : Unit = { if (cnt <= 0) throw new IllegalArgumentException PutBack.this.putBack(a) cnt = cnt - 1 } override def counted : this.type = this } protected[this] def flushFrom[B <% Seq[A]](i : Default[B]) = i.forget.reverse.foreach(_.reverse.foreach(putBack)) } abstract class Default[+A] extends PutBack[A] { import scala.collection.mutable.ListBuffer private[this] val lookahead = new ListBuffer[A] // = Nil override protected[this] def putBack(a : A) : Unit = a +: lookahead override protected def defaultPeek : A = throw new Predef.NoSuchElementException override def hasNext = !lookahead.isEmpty || super.hasNext /** used to fill lookahead buffer. <code>sz</code> can be used by implementations as a heauristic to determine how many elements are desired */ protected def fill(sz : Int) : Seq[A] private[BufferedIterator] def forget : List[A] = { val ret = lookahead.toList lookahead.clear ret } override def peekList(sz : Int) : Seq[A] = { if (sz == 0) return lookahead.readOnly else if (sz == 1) { if (!lookahead.isEmpty) return lookahead.readOnly fill(sz) match { case Seq.singleton(x) => lookahead += x case next => lookahead ++= next } return lookahead.readOnly } var sz0 = lookahead.length while (sz0 < sz) { val next = fill(sz - sz0) if (next.isEmpty) return lookahead.readOnly sz0 += next.length lookahead ++= next } lookahead.readOnly } override def next : A = { val lst = peekList(1) if (lst.isEmpty) throw new Predef.NoSuchElementException lookahead.remove(0) lst(0) } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?