TIL: Working With Iterators
Today I learned how to use Iterators to iterate through collections.
Like I mentioned in my post from a few days ago, the
Collection interface in java implement the
Iterable interface, which in tern implements the
Iterator interface. Because of this, we’re able to iterate over the contents of our collections to look through the contents of what’s stored.
In the example that I used back then, I’m pretty sure I handled things using a
for each method, rather than handling the problem using an iterator (as it was what made more sense to me at the time). Behind the scenes, the
for each method is actually using an iterator to handle its implementation.
But what about the cases where you might want to be removing things from the collection based on specific scenarios? I can’t do that normally when I iterate over a list as I have no way to cleanly delete the item. But explicitly using an iterator gives you this capability.
Using an iterator is easy if you are working with something like a collection as it is already being implemented for you. In order to take advantage of the capability, you need to create a new Iterator object from your collection object:
In this case I’ve now created a new iterator into that products
In order to start iterating through it, I just need to set up a while loop using the Iterator method
hasNext to constantly scan to see if there are more items in the collection:
In this case we’ll iterate through the
products List and print out each of the products:
It’s really that simple to use.
Iterator only has four basic methods to it:
hasNext()- returns a boolean whether or not there are anymore items in the collection
remove()- removes the current object from the collection object (more on this soon)
next()- gets the next value from the collection and moves where the iterator is pointing
forEachRemaining()- Another way of iterating over the collection
If I wanted to do what I did above using the
forEachRemaining, I could do the following:
One thing to note here is that when you’ve completed iterating to the end, that is your pointer has reached the end of the collection, there’s no way for you to wrap around back to the beginning. You will need to initialize the iterator again to start over.
Just to illustrate this point, I’ll update the code from above to print our whether or not the iterator
hasNext after going through the List once:
Removing as you go
As I mentioned at the beginning, really the big thing about using the Iterators explicitly is that you have the ability to remove items as you’re going. From what I read around the internet, this seems to be the big reason to use them in the first place.
So let’s look at the example from above again. Let’s say that while I’m iterating through the
products List I want to remove out any products that are more than 30lbs in weight (because I can’t be bothered to hurt my back). I could do the following to get rid of them:
Ironically enough, that example above actually throws a notice in IntelliJ telling that things could be written much simpler using the
I guess it just comes down to a matter of personal preference and readability? Knowing this now, I’m not really sure when I would ever choose to use an explicit iterator over just going through the List myself.
As I was doing some research for all of this, I found out that there are
ListIterators that behave much in the same way that normal Iterators work, but with a few different bonuses.
This post is already starting to get long though, so I think I’ll save that for tomorrow.
To me, it almost seems like using explicit Iterators is redundant at this point. It seems to me that pretty much everything uses them already behind the scenes, with less effort on the users ends… so I’m not sure how much I’ll use them.
Hopefully you found this useful and were able to learn something along with me. As always, sample code from this post is available in my github repo.