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.

For reference

Your opinion matters
Please write your valuable feedback about DataFlair on Google

courses

DataFlair Team

The DataFlair Team provides industry-driven content on programming, Java, Python, C++, DSA, AI, ML, data Science, Android, Flutter, MERN, Web Development, and technology. Our expert educators focus on delivering value-packed, easy-to-follow resources for tech enthusiasts and professionals.

Leave a Reply

Your email address will not be published. Required fields are marked *