Scala Iterator: A Cheat Sheet to Iterators in Scala
Scala course with real-time projects Start Now!!
We believe you’ve come here after all other collections. Before proceeding, you should read up on Scala Tuples, another kind of collection. In this tutorial on Scala Iterator, we will discuss iterators, how to create iterator in Scala and process them, and what methods to call on them.
So, let’s begin Scala Iterator Tutorial.
An Introduction to Iterators in Scala
After collections like Lists, Sets, and Maps, we will discuss a way to iterate on them(how we can access their elements one by one).
Two important methods in Scala Iterator are next() and hasNext. hasNext will tell if there is another element to return, while next() will return that element.
Declaring a Scala Iterator
Basically, to declare an iterator in Scala over a collection, we pass values to Iterator().
scala> val it=Iterator(7,8,9,2,3) it: Iterator[Int] = non-empty iterator
Accessing values with a Scala Iterator
We take this iterator:
scala> val it=Iterator(2,4,3,7,9) it: Iterator[Int] = non-empty iterator
Hence, let’s take a simple while loop to iterate:
scala> while(it.hasNext){ | println(it.next())}
2
4
3
7
9
If we hadn’t provided the println() to it.next(), it would print nothing. Also, once it reaches the end of the iterator, the iterator is now empty.
Determining Largest and Smallest Elements
We can use it.min and it.max to determine the largest and smallest elements in a Scala iterator.
a. min
This will return the smallest value in the Scala iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.min res1: Int = 2
b. max
This Scala Iterator will return the largest value in the iterator.
scala> it.max java.lang.UnsupportedOperationException: empty.max at scala.collection.TraversableOnce.max(TraversableOnce.scala:229) at scala.collection.TraversableOnce.max$(TraversableOnce.scala:227) at scala.collection.AbstractIterator.max(Iterator.scala:1432) ... 28 elided
Wow, okay, we must declare the iterator again since it’s empty now.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator
And now:
scala> it.max res3: Int = 9
So, let’s check if the Scala iterator has exhausted now:
scala> it.hasNext res4: Boolean = false
Yes. Yes, it has.
Scala Iterator Length
Further, we can use either of two methods- size and length.
a. size
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.size res5: Int = 5
b. length
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.length res6: Int = 5
Methods to Call on an Iterator in Scala
Next, here are some common methods we can call on an iterator:
a. def hasNext: Boolean
If the Scala iterator has another element to return, this returns true; otherwise, false.
scala> it.hasNext res7: Boolean = true scala> while(it.hasNext){it.next()} scala> it.hasNext res9: Boolean = false
b. def next(): A
Now, this returns the next element from the iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.next() res10: Int = 3 scala> it.next() res11: Int = 2 scala> it.next() res12: Int = 4 scala> it.next() res13: Int = 9 scala> it.next() res14: Int = 7 scala> it.next()
java.util.NoSuchElementException: next on empty iterator at scala.collection.Iterator$$anon$2.next(Iterator.scala:38) at scala.collection.Iterator$$anon$2.next(Iterator.scala:36) at scala.collection.IndexedSeqLike$Elements.next(IndexedSeqLike.scala:60) ... 28 elided
c. def ++(that: => Iterator[A]): Iterator[A]
This concatenates two Scala iterators.
scala> val a=Iterator(1,2,3).++(Iterator(5,6,7)) a: Iterator[Int] = non-empty iterator scala> while(a.hasNext){println(a.next())}
1
2
3
5
6
7
d. def addString(b: StringBuilder): StringBuilder
This appends the elements of the Scala iterator to a String Builder and returns it.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.addString(new StringBuilder()) res18: StringBuilder = 32497
e. def addString(b: StringBuilder, sep: String): StringBuilder
This lets us include a separator for the above functionality.
scala> it.addString(new StringBuilder(),"*") res19: StringBuilder = 3*2*4*9*7
f. def buffered: BufferedIterator[A]
This returns a buffered iterator from the iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.buffered res20: scala.collection.BufferedIterator[Int] = non-empty iterator
g. def contains(elem: Any): Boolean
If the Scala iterator contains element elem, this returns true; otherwise, false.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.contains(9) res21: Boolean = true scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.contains(8) res22: Boolean = false
h. def copyToArray(xs: Array[A], start: Int, len: Int): Unit
This copies the elements of the array, beginning at index start, and for length len, into an Array.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> var arr=Array(0,0,0,0,0,0,0,0,0,0,0) arr: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) scala> it.copyToArray(arr,2,3) scala> arr res28: Array[Int] = Array(0, 0, 3, 2, 4, 0, 0, 0, 0, 0, 0)
i. def count(p: (A) => Boolean): Int
This counts the number of elements that satisfy a predicate and returns this count.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.count(x=>{x%2!=0}) res29: Int = 3
j. def drop(n: Int): Iterator[A]
This moves the iterator n places ahead. If n is greater than the iterator’s length, this simply exhausts it.
scala> var it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it=it.drop(2) it: Iterator[Int] = non-empty iterator scala> it.next() res35: Int = 4 scala> it=it.drop(4) it: Iterator[Int] = empty iterator scala> it.next()
java.util.NoSuchElementException: next on empty iterator at scala.collection.Iterator$$anon$2.next(Iterator.scala:38) at scala.collection.Iterator$$anon$2.next(Iterator.scala:36) at scala.collection.IndexedSeqLike$Elements.next(IndexedSeqLike.scala:60) ... 28 elided
k. def dropWhile(p: (A) => Boolean): Iterator[A]
This keeps advancing the iterator as long as the predicate is satisfied.
scala> var it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it=it.dropWhile(x=>{x<4}) it: Iterator[Int] = non-empty iterator scala> it.next() res37: Int = 4 scala> it.next() res38: Int = 9 scala> it.next() res39: Int = 7
l. def duplicate: (Iterator[A], Iterator[A])
This creates a duplicate of the iterator that will iterate over the same sequence of values.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it1=it.duplicate it1: (Iterator[Int], Iterator[Int]) = (non-empty iterator,non-empty iterator)
m. def exists(p: (A) => Boolean): Boolean
If the predicate holds true for some values in the iterator, this returns true; otherwise, false.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.exists(x=>{x%3==0}) res41: Boolean = true scala> it.exists(x=>{x%5==0}) res42: Boolean = false
n. def filter(p: (A) => Boolean): Iterator[A]
This filters out such elements (see above)
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it1=it.filter(x=>{x%3==0}) it1: Iterator[Int] = non-empty iterator scala> it1.next() res44: Int = 3 scala> it1.next() res45: Int = 9 scala> it1.next()
java.util.NoSuchElementException: next on empty iterator at scala.collection.Iterator$$anon$2.next(Iterator.scala:38) at scala.collection.Iterator$$anon$2.next(Iterator.scala:36) at scala.collection.Iterator$$anon$12.next(Iterator.scala:516) ... 28 elided
o. def filterNot(p: (A) => Boolean): Iterator[A]
Parallelly, this will create a new iterator with only those elements that do not satisfy the predicate.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it1=it.filterNot(x=>{x%3==0}) it1: Iterator[Int] = non-empty iterator scala> it1.next() res47: Int = 2 scala> it1.next() res48: Int = 4 scala> it1.next() res49: Int = 7 scala> it1.next()
p. def find(p: (A) => Boolean): Option[A]
This returns the first value, if any, that satisfies the predicate.
scala> val it1=it.find(x=>{x%3==0}) it1: Option[Int] = Some(3)
This creates an Option.
q. def forall(p: (A) => Boolean): Boolean
If the predicate holds true for all values in the Scala iterator, this returns true; otherwise, false.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.forall(x=>{x%3==0}) res51: Boolean = false
r. def hasDefiniteSize: Boolean
If the iterator is empty, this returns true; otherwise, false.
scala> it.hasDefiniteSize res56: Boolean = true scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.hasDefiniteSize res57: Boolean = false
s. def indexOf(elem: B): Int
This returns the index of the first occurrence of the element elem in the Scala iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.indexOf(2) res58: Int = 1
t. def indexWhere(p: (A) => Boolean): Int
This returns the index of the first value that satisfies the predicate. If there’s none, it returns -1.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.indexWhere(x=>{x%7==0}) res60: Int = 4 scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.indexWhere(x=>{x%8==0}) res61: Int = -1
u. def isEmpty: Boolean
If hasNext returns false, then the iterator is empty.
scala> it.isEmpty res62: Boolean = true scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.next() res63: Int = 3 scala> it.hasNext res64: Boolean = true scala> it.isEmpty res65: Boolean = false
v. def isTraversableAgain: Boolean
If we can repeatedly traverse the iterator, this returns true; otherwise, false.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.isTraversableAgain res66: Boolean = false
w. def length: Int
Here, this returns the number of elements in the iterator. Once we’ve called this method, the iterator exhausts.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.length res69: Int = 5 scala> it res70: Iterator[Int] = empty iterator
x. def map[B](f: (A) => B): Iterator[B]
This applies the function to every value in the iterator and then returns a new iterator from this.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it1=it.map(x=>{x*x}) it1: Iterator[Int] = non-empty iterator scala> it1.next() res72: Int = 9 scala> it1.next() res73: Int = 4 scala> it1.next() res74: Int = 16 scala> it1.next() res75: Int = 81 scala> it1.next() res76: Int = 49
y. def max: A
This returns the largest element from the Scala iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.max res77: Int = 9
z. def min: A
This returns the smallest element from the iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.min res78: Int = 2
aa. def mkString: String
This represents all the elements of the iterator as a String.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.mkString res79: String = 32497
ab. def mkString(sep: String): String
This allows us to declare a separator for the same (see above)
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.mkString("*") res80: String = 3*2*4*9*7
ac. def nonEmpty: Boolean
If the iterator in Scala is empty, this returns false; otherwise, true.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.nonEmpty res81: Boolean = true scala> while(it.hasNext){it.next()} scala> it.nonEmpty res83: Boolean = false
ad. def product: A
This multiplies all elements from the iterator and returns the result.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.product res92: Int = 1512
ae. def sameElements(that: Iterator[_]): Boolean
If both iterators produce the same elements in the same order, this returns true; otherwise, false.
val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it1=Iterator(3,4,2,9,7) it1: Iterator[Int] = non-empty iterator scala> it.sameElements(it1) res93: Boolean = false scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it2=Iterator(3,2,4,9,7) it2: Iterator[Int] = non-empty iterator scala> it.sameElements(it2) res99: Boolean = true
af. def seq: Iterator[A]
This returns a sequential view of the iterator in Scala.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.seq res100: Iterator[Int] = non-empty iterator scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> for(i<-it.seq){println(i)}
3
2
4
9
7
ag. def size: Int
This returns the size of the iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.size res102: Int = 5
ah. def slice(from: Int, until: Int): Iterator[A]
This creates a new iterator with elements from from until until.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it1=it.slice(1,4) it1: Iterator[Int] = non-empty iterator scala> while(it1.hasNext){println(it1.next())}
2
4
9
ai. def sum: A
This returns the sum of all elements in the Scala iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.sum res1: Int = 25
aj. def take(n: Int): Iterator[A]
This returns the first n values from the iterator, or the entire iterator, whichever is shorter.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it1=it.take(3) it1: Iterator[Int] = non-empty iterator scala> while(it1.hasNext){println(it1.next())}
3
2
4
ak. def toArray: Array[A]
This returns an Array from the elements of the iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.toArray res4: Array[Int] = Array(3, 2, 4, 9, 7)
al. def toBuffer: Buffer[B]
This returns a Buffer from the iterator’s elements.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.toBuffer res5: scala.collection.mutable.Buffer[Int] = ArrayBuffer(3, 2, 4, 9, 7)
am. def toIterable: Iterable[A]
This returns a Scala iterable holding all elements of the iterator in Scala. This doesn’t terminate for infinite iterators. Let’s take a Scala Iterable Example.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.toIterable res6: Iterable[Int] = Stream(3, ?) an. def toIterator: Iterator[A]
Basically, this returns a new iterator from the iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> val it1=it.toIterator it1: Iterator[Int] = non-empty iterator scala> while(it1.hasNext){println(it1.next())}
3
2
4
9
7
an. def toList: List[A]
This Scala iterator to list returns a List from the iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.toList res9: List[Int] = List(3, 2, 4, 9, 7) ap. def toSeq: Seq[A]
This returns a Sequence from the iterator.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.toSeq res11: Seq[Int] = Stream(3, ?)
ao. def toString(): String
This represents the iterator as a String.
scala> val it=Iterator(3,2,4,9,7) it: Iterator[Int] = non-empty iterator scala> it.toString res12: String = non-empty iterator
ap. def zip[B](that: Iterator[B]): Iterator[(A, B)
This returns a new Scala iterator holding pairs of corresponding elements in the iterator. How many elements does this return? Whatever’s minimum of the sizes of both iterators.
scala> val it1=Iterator(0,0,0,0,0,0,0,0,0,0) it1: Iterator[Int] = non-empty iterator scala> it.zip(it1) res14: Iterator[(Int, Int)] = non-empty iterator
So, this was all about Scala Iterators. Hope you like our explanation.
Conclusion
Finally, we have seen Scala iterators. Moreover, we also discuss the ways to access collection elements one by one. Furthermore, if you have any query, feel free to ask in the comment section.
Your opinion matters
Please write your valuable feedback about DataFlair on Google