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 + -
显示快捷键?