Home > Articles > Software Development & Management

  • Print
  • + Share This
This chapter is from the book

This chapter is from the book

Internal Iterators versus External Iterators

Internal Iterators versus External Iterators

While either an internal iterator or an external iterator will do the basic job of stepping through an aggregate, there are some practical differences to consider. External iterators certainly have some advantages. For example, when you use an external iterator, the client drives the iteration. With an external iterator, you won’t call next until you are good and ready for the next element. With an internal iterator, by contrast, the aggregate relentlessly pushes the code block to accept item after item.

Most of the time, this difference does not matter. But what if you are trying to merge the contents of two sorted arrays into a single array that was itself sorted? This kind of merge is actually fairly easy with an external iterator like ArrayInterator: We simply create an iterator for the two input arrays and then merge the arrays by repeatedly pushing the smallest value from either of the iterators onto the output array.

def merge(array1, array2)
  merged = []

  iterator1 = ArrayIterator.new(array1)
  iterator2 = ArrayIterator.new(array2)

  while( iterator1.has_next? and iterator2.has_next? )
    if iterator1.item < iterator2.item
      merged << iterator1.next_item
    else
      merged << iterator2.next_item
    end
  end

  # Pick up the leftovers from array1

  while( iterator1.has_next?)
    merged << iterator1.next_item
  end

  # Pick up the leftovers from array2

  while( iterator2.has_next?)
    merged << iterator2.next_item
  end

  merged
end

I am not sure how you would implement a merge like this using internal iterators.

A second advantage of external iterators is that, because they are external, you can share them—you can pass them around to other methods and objects. Of course, this is a bit of a double-edged sword: You get the flexibility but you also have to know what you are doing. In particular, beware of multiple threads getting hold of a non-thread-safe external iterator.

The main thing that internal iterators have going for them is simplicity and code clarity. External iterators have that extra moving part, the iterator object. In our array example, we not only have the array and the client code, but also the separate ArrayInterator object. With internal iterators, there is no separate iterator object to manage (“Did I call next yet?”), just a stretch of more or less in-line code.

  • + Share This
  • 🔖 Save To Your Account