iterator.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 686 行 · 第 1/2 页
SCALA
686 行
/* __ *\** ________ ___ / / ___ Scala API **** / __/ __// _ | / / / _ | (c) 2003-2008, LAMP/EPFL **** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **** /____/\___/_/ |_/____/_/ | | **** |/ **\* */// $Id: Iterator.scala 14494 2008-04-04 09:40:48Z washburn $package scalaimport Predef._import collection.mutable.{Buffer, ListBuffer}/** The <code>Iterator</code> object provides various functions for * creating specialized iterators. * * @author Martin Odersky * @author Matthias Zenger * @version 1.2, 10/02/2007 */object Iterator { val empty = new Iterator[Nothing] { def hasNext: Boolean = false def next(): Nothing = throw new NoSuchElementException("next on empty iterator") } /** * @param x the element * @return the iterator with one single element */ def single[a](x: a) = new Iterator[a] { private var hasnext = true def hasNext: Boolean = hasnext def next(): a = if (hasnext) { hasnext = false; x } else throw new NoSuchElementException("next on empty iterator") } def fromValues[a](xs: a*) = xs.elements /** * @param xs the array of elements * @see also: RandomAccessSeq.elements and slice */ def fromArray[a](xs: Array[a]): Iterator[a] = fromArray(xs, 0, xs.length) /** * @param xs the array of elements * @param start the start index * @param length the length * @see also: RandomAccessSeq.elements and slice */ @throws(classOf[NoSuchElementException]) def fromArray[a](xs: Array[a], start: Int, length: Int): Iterator[a] = new BufferedIterator.Advanced[a] { private var i = start val end = if (start + length < xs.length) start + length else xs.length override def hasNext: Boolean = i < end def next: a = if (hasNext) { val x = xs(i) ; i += 1 ; x } else throw new NoSuchElementException("next on empty iterator") override protected def defaultPeek : a = throw new NoSuchElementException("no lookahead") override def peekList(sz: Int): Seq[a] = xs.slice(i, if (i + sz > xs.length) xs.length else i + sz) } /** * @param str the given string * @return the iterator on <code>str</code> * @deprecated replaced by <code>str.elements</code> */ @deprecated def fromString(str: String): Iterator[Char] = new BufferedIterator.Advanced[Char] { private var i = 0 private val len = str.length() override def hasNext = i < len def next = { val c = str charAt i; i += 1; c } override protected def defaultPeek : Char = throw new NoSuchElementException override def peekList(sz: Int): Seq[Char] = str.substring(i, if (i + sz > str.length) str.length else i + sz) } /** * @param n the product arity * @return the iterator on <code>Product<n></code>. */ def fromProduct(n: Product): Iterator[Any] = new Iterator[Any] { private var c: Int = 0 private val cmax = n.productArity def hasNext = c < cmax def next() = { val a = n productElement c; c += 1; a } } /** * @deprecated use <code>fromProduct</code> instead. */ @deprecated def fromCaseClass(n: Product) = fromProduct(n) /** Create an iterator with elements * <code>e<sub>n+1</sub> = e<sub>n</sub> + 1</code> * where <code>e<sub>0</sub> = start</code> * and <code>e<sub>i</sub> < end</code>. However, * if <code>start ≥ end</code>, then it will return an empty range. * * @param start the start value of the iterator * @param end the end value of the iterator * @return the iterator with values in range <code>[start;end)</code>. */ def range(start: Int, end: Int): Iterator[Int] = range(start, end, 1) /** Create an iterator with elements * <code>e<sub>n+1</sub> = e<sub>n</sub> + step</code> * where <code>e<sub>0</sub> = start</code> * and elements are in the range between <code>start</code> (inclusive) * and <code>end</code> (exclusive) * * @param start the start value of the iterator * @param end the end value of the iterator * @param step the increment value of the iterator (must be positive or negative) * @return the iterator with values in range <code>[start;end)</code>. */ @throws(classOf[NoSuchElementException]) def range(start: Int, end: Int, step: Int) = new Iterator[Int] { private var i = start def hasNext: Boolean = (step <= 0 || i < end) && (step >= 0 || i > end) def next(): Int = if (hasNext) { val j = i; i += step; j } else throw new NoSuchElementException("next on empty iterator") } /** Create an iterator with elements * <code>e<sub>n+1</sub> = step(e<sub>n</sub>)</code> * where <code>e<sub>0</sub> = start</code> * and elements are in the range between <code>start</code> (inclusive) * and <code>end</code> (exclusive) * * @param start the start value of the iterator * @param end the end value of the iterator * @param step the increment function of the iterator, must be monotonically increasing or decreasing * @return the iterator with values in range <code>[start;end)</code>. */ @throws(classOf[NoSuchElementException]) def range(start: Int, end: Int, step: Int => Int) = new Iterator[Int] { private val up = step(start) > start private val down = step(start) < start private var i = start def hasNext: Boolean = (!up || i < end) && (!down || i > end) def next(): Int = if (hasNext) { val j = i; i = step(i); j } else throw new NoSuchElementException("next on empty iterator") } /** Create an iterator with elements * <code>e<sub>n+1</sub> = e<sub>n</sub> + 1</code> * where <code>e<sub>0</sub> = start</code>. * * @param start the start value of the iterator * @return the iterator starting at value <code>start</code>. */ def from(start: Int): Iterator[Int] = from(start, 1) /** Create an iterator with elements * <code>e<sub>n+1</sub> = e<sub>n</sub> + step</code> * where <code>e<sub>0</sub> = start</code>. * * @param start the start value of the iterator * @param step the increment value of the iterator * @return the iterator starting at value <code>start</code>. */ def from(start: Int, step: Int): Iterator[Int] = from(start, {x:Int => x + step}) /** Create an iterator with elements * <code>e<sub>n+1</sub> = step(e<sub>n</sub>)</code> * where <code>e<sub>0</sub> = start</code>. * * @param start the start value of the iterator * @param step the increment function of the iterator * @return the iterator starting at value <code>start</code>. */ def from(start: Int, step: Int => Int): Iterator[Int] = new Iterator[Int] { private var i = start override def hasNext: Boolean = true def next: Int = { val j = i; i = step(i); j } }}/** Iterators are data structures that allow to iterate over a sequence * of elements. They have a <code>hasNext</code> method for checking * if there is a next element available, and a <code>next</code> method * which returns the next element and discards it from the iterator. * * @author Martin Odersky, Matthias Zenger * @version 1.2, 15/03/2004 */trait Iterator[+A] { /** Does this iterator provide another element? */ def hasNext: Boolean /** Returns the next element. */ def next(): A /** Returns a new iterator that iterates only over the first <code>n</code> * elements. * * @param n the number of elements to take * @return the new iterator */ @throws(classOf[NoSuchElementException]) def take(n: Int) = new Iterator[A] { var remaining = n def hasNext = remaining > 0 && Iterator.this.hasNext def next(): A = if (hasNext) { remaining -= 1; Iterator.this.next } else throw new NoSuchElementException("next on empty iterator") } /** Removes the first <code>n</code> elements from this iterator. * * @param n the number of elements to drop * @return the new iterator */ def drop(n: Int): Iterator[A] = if (n > 0 && hasNext) { next; drop(n - 1) } else this /** A sub-iterator of <code>until - from elements * starting at index <code>from</code> * * @param from The index of the first element of the slice * @param until The index of the element following the slice */ def slice(from: Int, until: Int): Iterator[A] = drop(from).take(until - from) /** Returns a new iterator that maps all elements of this iterator * to new elements using function <code>f</code>. */ def map[B](f: A => B): Iterator[B] = new Iterator[B] { def hasNext = Iterator.this.hasNext def next() = f(Iterator.this.next) } /** Returns a new iterator that first yields the elements of this * iterator followed by the elements provided by iterator <code>that</code>. * @deprecated use <code>++</code> */ def append[B >: A](that: Iterator[B]) = new Iterator[B] { def hasNext = Iterator.this.hasNext || that.hasNext def next() = if (Iterator.this.hasNext) Iterator.this.next else that.next } /** Returns a new iterator that first yields the elements of this * iterator followed by the elements provided by iterator <code>that</code>. */ def ++[B >: A](that: => Iterator[B]) = new Iterator[B] { // optimize a little bit to prevent n log n behavior. var what : Iterator[B] = Iterator.this def hasNext = if (what.hasNext) true else if (what eq Iterator.this) { what = that what.hasNext } else false def next = { hasNext; what.next } } /** Applies the given function <code>f</code> to each element of * this iterator, then concatenates the results. * * @param f the function to apply on each element. * @return an iterator over <code>f(a<sub>0</sub>), ... , * f(a<sub>n</sub>)</code> if this iterator yields the * elements <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. */ @throws(classOf[NoSuchElementException]) def flatMap[B](f: A => Iterator[B]): Iterator[B] = new Iterator[B] { private var cur: Iterator[B] = Iterator.empty def hasNext: Boolean = if (cur.hasNext) true else if (Iterator.this.hasNext) { cur = f(Iterator.this.next) hasNext } else false def next(): B = if (cur.hasNext) cur.next else if (Iterator.this.hasNext) { cur = f(Iterator.this.next) next } else throw new NoSuchElementException("next on empty iterator") } protected class PredicatedIterator(p : A => Boolean) extends BufferedIterator.Default[A] { protected def doEnd : Boolean = false protected override def fill(sz: Int): Seq[A] = { while (true) { if (!Iterator.this.hasNext) return Nil val ret = Iterator.this.next if (p(ret)) return ret :: Nil if (doEnd) return Nil } throw new Error } } protected class TakeWhileIterator(p : A => Boolean) extends PredicatedIterator(p) { private var ended = false override protected def doEnd = { ended = true; true } override protected def fill(sz : Int) : Seq[A] = if (ended) Nil else super.fill(sz) } /** Returns an iterator over all the elements of this iterator that * satisfy the predicate <code>p</code>. The order of the elements * is preserved. * * @param p the predicate used to filter the iterator. * @return the elements of this iterator satisfying <code>p</code>. */ def filter(p: A => Boolean): Iterator[A] = new PredicatedIterator(p) /** Returns an iterator over the longest prefix of this iterator such that * all elements of the result satisfy the predicate <code>p</code>. * The order of the elements is preserved. * * @param p the predicate used to filter the iterator. * @return the longest prefix of this iterator satisfying <code>p</code>. */ def takeWhile(p: A => Boolean): Iterator[A] = new TakeWhileIterator(p) /** Skips longest sequence of elements of this iterator which satisfy given
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?