iterator.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 686 行 · 第 1/2 页

SCALA
686
字号
   *  predicate <code>p</code>, and returns an iterator of the remaining elements.   *   *  @param p the predicate used to skip elements.   *  @return  an iterator consisting of the remaining elements   */  def dropWhile(p: A => Boolean): Iterator[A] =    if (hasNext) {      val x = next      if (p(x)) dropWhile(p)      else Iterator.single(x) append this    } else this  /** Return an iterator formed from this iterator and the specified iterator   *  <code>that</code> by associating each element of the former with   *  the element at the same position in the latter.   *  If one of the two iterators is longer than the other, its remaining elements are ignored.   *   *  @return     an iterator yielding <code>{a<sub>0</sub>,b<sub>0</sub>},   *              {a<sub>1</sub>,b<sub>1</sub>}, ...</code> where   *              <code>a<sub>i</sub></code> are the elements from this iterator   *              and <code>b<sub>i</sub></code> are the elements from iterator   *              <code>that</code>.   */  def zip[B](that: Iterator[B]) = new Iterator[(A, B)] {    def hasNext = Iterator.this.hasNext && that.hasNext    def next = (Iterator.this.next, that.next)  }  /** Return an iterator that pairs each element of this iterator   *  with its index, counting from 0.   *   *  @param start the index of the first element.   *  @return      an iterator yielding <code>{a<sub>0</sub>,0},   *               {a<sub>1</sub>,1}...</code> where <code>a<sub>i</sub></code>   *               are the elements from this iterator.   */  def zipWithIndex = new Iterator[(A, Int)] {    var idx = 0    def hasNext = Iterator.this.hasNext    def next = {      val ret = (Iterator.this.next, idx)      idx += 1      ret    }  }  /** Apply a function <code>f</code> to all elements of this   *  iterable object.   *   *  @param  f   a function that is applied to every element.   */  def foreach(f: A => Unit) { while (hasNext) f(next) }  /** Apply a predicate <code>p</code> to all elements of this   *  iterable object and return <code>true</code> iff the predicate yields   *  <code>true</code> for all elements.   *   *  @param p the predicate   *  @return  <code>true</code> iff the predicate yields <code>true</code>   *           for all elements.   */  def forall(p: A => Boolean): Boolean = {    var res = true    while (res && hasNext) res = p(next)    res  }  /** Apply a predicate <code>p</code> to all elements of this   *  iterable object and return true, iff there is at least one   *  element for which <code>p</code> yields <code>true</code>.   *   *  @param p the predicate   *  @return  <code>true</code> iff the predicate yields <code>true</code>   *           for at least one element.   */  def exists(p: A => Boolean): Boolean = {    var res = false    while (!res && hasNext) res = p(next)    res  }  /** Tests if the given value <code>elem</code> is a member of this iterator.   *   *  @param elem element whose membership has to be tested.   *  @return     <code>true</code> iff there is an element of this iterator which   *              is equal (w.r.t. <code>==</code>) to <code>elem</code>.   */  def contains(elem: Any): Boolean = exists { _ == elem }  /** Find and return the first element of the iterable object satisfying a   *  predicate, if any.   *   *  @param p the predicate   *  @return  the first element in the iterable object satisfying   *           <code>p</code>, or <code>None</code> if none exists.   */  def find(p: A => Boolean): Option[A] = {    var res: Option[A] = None    while (res.isEmpty && hasNext) {      val e = next      if (p(e)) res = Some(e)    }    res  }  /** Combines the elements of this iterator together using the binary   *  operator <code>op</code>, from left to right, and starting with   *  the value <code>z</code>.   *   *  @return <code>op(... (op(op(z,a<sub>0</sub>),a<sub>1</sub>) ...),   *          a<sub>n</sub>)</code> if the iterator yields elements   *          <code>a<sub>0</sub>, a<sub>1</sub>, ..., a<sub>n</sub></code>.   */  def foldLeft[B](z: B)(op: (B, A) => B): B = {    var acc = z    while (hasNext) acc = op(acc, next)    acc  }  /** Combines the elements of this iterator together using the binary   *  operator <code>op</code>, from right to left, and starting with   *  the value <code>z</code>.   *   *  @return <code>a<sub>0</sub> op (... op (a<sub>n</sub> op z)...)</code>   *          if the iterator yields elements <code>a<sub>0</sub>, a<sub>1</sub>, ...,   *          a<sub>n</sub></code>.   */  def foldRight[B](z: B)(op: (A, B) => B): B = {    def fold(z: B): B = if (hasNext) op(next, fold(z)) else z    fold(z)  }  /** Similar to <code>foldLeft</code> but can be used as   *  an operator with the order of iterator and zero arguments reversed.   *  That is, <code>z /: xs</code> is the same as <code>xs foldLeft z</code>.   *   *  @param z the left argument of the first application of <code>op</code>   *           (evaluation occurs from left to right).   *  @param op the applied operator.   *  @return  the result value   *  @see     <code><a href="#foldLeft">foldLeft</a></code>.   */  def /:[B](z: B)(op: (B, A) => B): B = foldLeft(z)(op)  /** An alias for <code>foldRight</code>.   *  That is, <code>xs :\ z</code> is the same as <code>xs foldRight z</code>.   *   *  @param z the right argument of the first application of <code>op</code>   *           (evaluation occurs from right to left).   *  @param op the applied operator.   *  @return  the result value.   *  @see     <code><a href="#foldRight">foldRight</a></code>.   */  def :\[B](z: B)(op: (A, B) => B): B = foldRight(z)(op)  /** Combines the elements of this iterator together using the binary   *  operator <code>op</code>, from left to right   *  @param op  The operator to apply   *  @return <code>op(... op(a<sub>0</sub>,a<sub>1</sub>), ..., a<sub>n</sub>)</code>       if the iterator yields elements   *          <code>a<sub>0</sub>, a<sub>1</sub>, ..., a<sub>n</sub></code>.   *  @throws Predef.UnsupportedOperationException if the iterator is empty.   */  @throws(classOf[UnsupportedOperationException])  def reduceLeft[B >: A](op: (B, A) => B): B = {    if (hasNext) foldLeft[B](next)(op)    else throw new UnsupportedOperationException("empty.reduceLeft")  }  /** Combines the elements of this iterator together using the binary   *  operator <code>op</code>, from right to left   *  @param op  The operator to apply   *   *  @return <code>a<sub>0</sub> op (... op (a<sub>n-1</sub> op a<sub>n</sub>)...)</code>   *          if the iterator yields elements <code>a<sub>0</sub>, a<sub>1</sub>, ...,   *          a<sub>n</sub></code>.   *  @throws Predef.UnsupportedOperationException if the iterator is empty.   */  @throws(classOf[UnsupportedOperationException])  def reduceRight[B >: A](op: (A, B) => B): B = {    if (!hasNext) throw new UnsupportedOperationException("empty.reduceRight")    val x = next    if (hasNext) op(x, reduceRight(op))    else x  }  /** Returns a buffered iterator from this iterator.   */  def buffered: BufferedIterator[A] = new BufferedIterator.Default[A] {    protected def fill(sz : Int) = if (Iterator.this.hasNext) (Iterator.this.next) :: Nil else Nil  }  /** Returns a counted iterator from this iterator.   */  def counted = new CountedIterator[A] {    private var cnt = -1    def count = cnt    def hasNext: Boolean = Iterator.this.hasNext    def next: A = { cnt += 1; Iterator.this.next }  }  /** Creates two new iterators that both iterate over the same elements   *  than this iterator (in the same order).   *   *  @return a pair of iterators   */  def duplicate: (Iterator[A], Iterator[A]) = {    var xs: List[A] = Nil    var ahead: Iterator[A] = null    class Partner extends Iterator[A] {      var ys: List[A] = Nil      def hasNext: Boolean = Iterator.this.synchronized (        ((this == ahead) && Iterator.this.hasNext) ||        ((this != ahead) && (!xs.isEmpty || !ys.isEmpty || Iterator.this.hasNext))      )      def next: A = Iterator.this.synchronized {        if (this == ahead) {          val e = Iterator.this.next          xs = e :: xs; e        } else {          if (ys.isEmpty) {            ys = xs.reverse            xs = Nil          }          ys match {            case Nil =>              val e = Iterator.this.next              ahead = this              xs = e :: xs; e            case z :: zs =>              ys = zs; z          }        }      }    }    ahead = new Partner    (ahead, new Partner)  }  /** Fills the given array <code>xs</code> with the elements of   *  this sequence starting at position <code>start</code>.   *   *  @param  xs    the array to fill.   *  @param  start the starting index.   *  @pre          the array must be large enough to hold all elements.   */  def copyToArray[B >: A](xs: Array[B], start: Int) {    var i = start    while (hasNext) {      xs(i) = next      i += 1    }  }  /** Fills the given array <code>xs</code> with the elements of   *  this sequence starting at position <code>start</code>.  Like <code>copyToArray</code>,    *  but designed to accomodate IO stream operations.    *   *  @param  xs    the array to fill.   *  @param  start the starting index.   *  @param  sz    the maximum number of elements to be read.   *  @pre          the array must be large enough to hold <code>sz</code> elements.   */  def readInto[B >: A](xs: Array[B], start: Int, sz: Int) {    var i = start    while (hasNext && i - start < sz) {      xs(i) = next      i += 1    }  }  def readInto[B >: A](xs: Array[B], start: Int) {    readInto(xs, start, xs.length - start)  }  def readInto[B >: A](xs: Array[B]) {    readInto(xs, 0, xs.length)  }  /** Copy all elements to a buffer    *  @param   The buffer to which elements are copied   *  @return  The buffer to which elements are copied   */  def copyToBuffer[B >: A](dest: Buffer[B]) {    while (hasNext) dest += next  }  /** Transform this iterator into a list of all elements.   *   *  @return  a list which enumerates all elements of this iterator.   */  def toList: List[A] = {    val res = new ListBuffer[A]    while (hasNext) res += next    res.toList  }  /** Returns a string representation of the elements in this iterator. The resulting string   *  begins with the string <code>start</code> and is finished by the string   *  <code>end</code>. Inside, the string representations of elements (w.r.t.   *  the method <code>toString()</code>) are separated by the string   *  <code>sep</code>.   *  <p/>   *  Ex: <br/>   *  <code>List(1, 2, 3).mkString("(", "; ", ")") = "(1; 2; 3)"</code>   *   *  @param start starting string.   *  @param sep separator string.   *  @param end ending string.   *  @return a string representation of this iterable object.   */  def mkString(start: String, sep: String, end: String): String = {    val buf = new StringBuilder    addString(buf, start, sep, end).toString  }  /** Returns a string representation of this iterable object. The string   *  representations of elements (w.r.t. the method <code>toString()</code>)   *  are separated by the string <code>sep</code>.   *   *  @param sep separator string.   *  @return a string representation of this iterable object.   */  def mkString(sep: String): String = this.mkString("", sep, "")  /** Write all elements of this string into given string builder.   *   *  @param buf   ...   *  @param start the starting string   *  @param sep   the separator string   *  @param end   the ending string   *  @return      ...   */  def addString(buf: StringBuilder, start: String, sep: String, end: String): StringBuilder = {    buf.append(start)    val elems = this    if (elems.hasNext) buf.append(elems.next)    while (elems.hasNext) {      buf.append(sep); buf.append(elems.next)    }    buf.append(end)  }  override def toString = (if (hasNext) "non-empty" else "empty")+" iterator"}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?