Hello, Jim.
In this lesson, we are going to talk about what iterable and iterator interfaces are.
We would investigate source code of these two interfaces and also will answer what is the role of these
two interfaces in Java collections framework.
After this lesson, you will never confuse these two interfaces.
We are going to learn three types of iterator.
And at the end of the lesson, I also want to demo what least Iterator is and how it is different from
Iterator.
Let's start.
I believe you remember that first time when we looked at collection interface, we found that collection
interface is extended from iterable interface.
You remember that as you can see on this class diagram, iterable interface has only one method iterator.
This method should return object of iterate type.
That means that each implementation of collection interfacing Java should have iterator.
I believe that is all what we can say about iterable interface.
This interface is to tell that I'm the type that has iterator more interesting to talk about what an
iterator is and to answer this question, I suggest reviewing source code of iterator type in eclipse
in few words.
Iterator is a type that can go over each element in a container.
That's it.
You might be wondering, is it really so hard and separate type is needed?
It is not so hard, but imagine two simple cases.
You have array lists and linked list.
In our list we are together elements from the array by the indexes in the linked list.
We have to get the reference to the next node from each node to iterate over elements.
Can you see that the way how to iterate over each element, even in these two collections, is completely
different?
That's exactly the reason why we need to come up with some abstract type like Iterator to set the interface
that should be implemented by specific implementations of collection interface.
So let's sum up what Iterator is.
Iterator is an interface that allows access to the elements in container and navigation in collection,
including iteration or in other words, looping over each element in any collection without knowing
the details of implementation of specific collection.
Now we are going to run the interface of iterate the type it has to abstract and two default methods.
Let me explain what each of these methods is about.
Has an X method returns true or false?
It tells us whether the next element is present will use this method in loops to check if it was to
go on with our loop or we reached the end of the collection and we have to break the loop.
Next method returns the next element in connection.
Be careful.
This method may throw no such element exception and interrupt your program execution in case you called
next method.
But there are no any elements there.
That is a contract of the Iterator interface.
We can do nothing about that.
That's why before calling next method, we have to always call has next method remove method supposed
to remove the last element returned by next method and now attention.
This method can be called only once after each next method call.
We can't call two times next method and after that call two times remove method.
That is the way how Iterator should work in case you would call remove method without calling next method
or we'll call remove two times in a row in your program, your program will be stopped with illegal
state exception.
But there is more interesting thing here.
By default, remove method throws and support the separation exception.
That means that in case we would call this method, our program will be stopped with the exceptional
situation.
Now I'm going to say not only my opinion, but opinion of different engineers too.
It is senseless to declare method in the interface that is not needed.
Yes, exactly.
This exception here and support the separation exception tells us that by default this method is not
supported.
Don't do that during the implementation of your interfaces.
Why?
Let me explain here.
We can see a violation of one of the solid principles.
Can you guess what solid principle is violated in the Iterator interface?
Exactly.
High principle interface aggregation principle.
According to this principle, no client should be forced to depend on methods it doesn't use.
Originally, according to the documentation, Iterator type was created to iterate over elements, but
not to remove them.
How would I recommend implementing this?
I would create something like removable iterator that extends iterate type and would let client of my
code to decide whether they need to remove method or no, because right now each implementation of Iterator.
Interface has removed MassArt, even if it is not a that this is default MassArt and there is no need
to override it.
But this does not make life of engineers easier because we still can call, remove by mistake and rely
on the fact that this behavior should be supported in iterator.
Now, you know that there is an exception here.
The other side of this violation is that in the case in Java collections framework, engineers would
follow all or P principles, including interface aggregation principle.
There would be big bank of interfaces that is hard to learn and hard to remember and even harder to
maintain.
So as you can see, programming like everything else in our lives is all about tradeoffs and compromises.
The last but not the least massaged here in Interactor interface is for each remaining, this matter
takes function that should be applied for each element that remains in the container.
The usage of this message requires knowledge of functional programming in Java and no interfaces from
the Java Wattyl function package.
That's why today will not Damul work of this method.
But we will damage it in the lesson about functional programming.
OK, now when we know iterate the interface, I suggest learning how it works and to practice a bit.
And I would like to visualize the way how Massaponax and remove works.
Let's take a look at this slide.
I want you to imagine that Iterator works like a cursor, namely at the beginning.
It stands right before the first element.
When we call next method, it returns the next element to us.
And now cursor stands between the first and the second element in case we call next method one more
time cursor is moved to the position between second and the third element like you see on the slide.
Now, when we call remove method Iterator works as a backspace key on the Windows machines, it removes
elements that stands right before the cursor.
Does it make sense?
Now let's get back to Eclipse.
For the sake of the drama, I created this demo file to practice a bit with Iterator, let me run this
program and walk you through the different cases that are listed here.
At the beginning, I created the list of integers to play with, you already know this construction,
so there is nothing special for you here.
Now, let's iterate over each element in container.
I call iterate a method on our list that returns iterator object parametrized by integer type.
This means that when I will call next Masset iterate, I will reach an object of type integer like it
specified here in Diamond Operator, but not the object of type object.
After that we have while loop and I check in condition statement here was an iterator has an extra element
or no.
And if yes I want to print it to cancel next match it returns me means a reference to the next element
in my container.
Is everything clear here.
Haubert is the next example is more like practical type.
Some of my students that I taught offline feel concerned that they can use the same iterator once we
iterate it over all elements.
So after the previous loop, our iterator cursor is at the end of the container and has an X method
will return false.
That is exactly the reason why we see this console output here.
But what to do now?
We can use the same variable and initialize it with a new iterator object because no message to reset
courser obliterated back again to the beginning like we did here.
So that is fine.
Now I want to them how remove method works.
Let's remove all even numbers from our container we call next method to get the element from the container.
After that, we check whether this number is A1 and if yes, then we remove it.
You can see that I don't violate the rules of remove method usage.
I call remove method only after I called next method.
And also there are no multiple locations of remove method.
You also can notice that iterator that is implemented in at least overwrites remove Masset and doesn't
throw and supports the separation exception like the full implementation of Remove Massud does.
Now, if you are not familiar with the exception topic yet, let me show you an example.
What exception means and how the writer may throw exceptions.
Lattman comments these lines of code I initialised again my iterative variable with the new iterator
object.
After that I call Remove Masset without calling.
Next Masset.
Let me run my program now.
And here we can see illegal state exception.
The same exceptions will be thrown in case we would call remove Massud two times in a row.
That is something what you have to remember at the end of the lesson I will share with your home task
where you will have opportunity to practice your skills in writing your custom iterators.
Let me comment these lines to be able to execute code that is written after this one.
Let me also show one more important exception that might be thrown by Iterator that is concurrent modification,
exception and uncommon these lines of code and will damage to you.
Imagine that we created Iterator and when we started iteration, we removed elements from the container,
but not with the help of Iterator, but just by using the removed method of our list.
This is just an example.
In real life, it might happen that you created an iterator on the list that is shared between different
threats of execution and somebody in another thread did some modifications to your list.
And after we would call next method, we would see concurrent modification exception.
That means somebody modified the collection after Iterator had been created.
Iterate an object, noticed that and want to let us know that collections that we are iterating over
is not up to date.
And that information about elements that I will read with the help of this iterator is not relevant
anymore.
This type of iterator is called fail fast iterator.
That is default implementation of iterators in majority of collection implementations that are not developed
to be used in multithreaded environment.
What to do in this case, in case you have iterate to make sure there is no other place in your code
where you modify the same collection simultaneously.
If you do modify collections from different sets of execution, then you need failsafe iterator.
That is a second type of iterator that usually called failsafe.
Let me Corman's the concurrent modification demo code to be able to proceed with the next one and I
ran the program again.
Usually thread safe implementation of collections also implements failsafe iterator to explain in short
how it works without going deep into the details.
Failsafe Iterate that makes a copy of the internal data structure and iterate over the corporate data
structure.
And a structural modification done to the Iterator doesn't affect the copied data structure.
So original data structure is changed.
This type of iterator creates a snapshot and iterate over elements in this snapshot.
The drawback of such iterator type is obvious.
In some cases, you may not receive latest and up to date version of elements in case collection is
modified from the different threats.
But sometimes it might be not critical for you.
Here we have thread safe list implementation copy and write a list I initialize.
It was elements that are in our integers list.
I create iterator interface of the that is the same everywhere.
That's why I use the same variables that I had created.
As I already mentioned, failsafe iterators creates a snapshot of the container to prove this.
Here I add another integer to this container and now when I iterate over elements and as in previous
example, I remove elements from collection.
Without Iterator, I still bring elements from the container to the console.
But why not print the collection to console?
It has only one number that we added after iterator creation.
This proves that Iterator creates a snapshot with elements, and this snapshot is not updated as we
update collection after creation of Iterator.
There is also a third type of iterator that is called weakly consistent.
It is called so because this type of iterator can reflect some, but not necessarily all of the changes
that have been made to the collection since Iterator is created.
Let me show you this.
I declare a new variable of collection type parametrized with integer type an aggregate object of concurrent
linked deck.
This collection implementation has weekly consistent Iterator implementation.
I create an iterator and now attention similar to the previous example.
I add new integer here and now.
When I'm iterating over each element, I can see that new integer already was taken into account here.
But as it is said in the documentation, there is no guarantee that all updates to the collection will
be taken into account by the moment Iterator would reach the specific element.
I understand now what is really consistent iterator.
So now we may say that we learned three types of the iterator.
The last thing that I would like to learn with you today is a list iterator.
Let's look at this interface.
The first thing that you can see is that list rate that extends iterate the interface.
The main feature that is introduced list, right, is to iterate over elements in the reverse direction.
If Iterator can go over elements from the beginning to the end, the list rate that can go from the
end to the beginning.
It also declares mass that absent in iterator interface, Zaya has Hesperus.
It is similar to his next.
But check if there any element in another direction, previs returns the reference to the previous element
in the container next index to get the index of the next element, previous index it returns.
The element that would be returned by previous MassArt set replaces the last element that was returned.
And this is important to understand.
It replaces elements that was returned after the next or previous method in case that method is called
without calling next the previous method before that illegal state exception strong.
Add method adds element to the container so you can see a few more important features of the list iterator.
It also allows us to add element to the container during the iteration over elements or to substitute
elements.
Let's look at the list, iterator them.
Now, I created a separate file for that.
Let me also execute this program.
I have the same container was integers as in previous example.
The list interface declares list.
Iterate the method.
As you remember, this method returns as the objects of list iterator type.
One more interesting feature.
We can get at least iterator from the specific position if we need.
I can't imagine the case when I would use it, but it is interesting feature to know about.
List Iterator, for example.
Here I set List Iterator as a second index.
Here is a position of the cursor in the index zero here, position of the cursor in the index one and
here is two.
So the next goal of the previous method should return number two.
And now you can see in the console output that two is returned.
Now I want to update this element.
I call set method and pass twenty two this method.
So the elements that was returned previously is substituted with twenty.
So my next goal of the next method should return twenty and he and console you can see at least Iterator
works exactly in the way we expect it to work.
In case I want to add an element with the help of this iterator, I call add method and the item is
inserted right before the cursor.
So in case I added twenty one, I can get it now by calling the previous method and here's twenty one
and remove mass at the last item that was returned either by next or previous method.
In this case after location of remove method twenty one will be removed and here we printed all elements
to console to prove this.
Now, I believe you have a full understanding of how Étretat enlisted radar works.
Let's recap what we have learned today.
Today, we learned what iterable is.
We also understand what Iterator is now.
We know the difference between these two interfaces when real examples, we saw how Iterator works in
this lesson.
We saw what exceptions might be thrown by iterator, including concurrent modification, exception,
illegal state exception, unsupported aliment exception and no such aliment exception.
We learned three types of iterator fail fast, fail safe and weakly consistent.
And at the end of the lesson we learned at least iterator and how it works.
Now let's review your homework.
In short, you have to coordinate exercises here, you have to implement Iterator and Lisa the for the
default Miley's class that you implemented in scoping her homework about lists, read attentively all
the requirements here I prepared for you method signatures and description of interfaces.
All you have to do is implement methods.
You will see here some requirements related to exceptions in case you are not familiar with exceptions
topic.
There is absolutely no harm because I wrote the line of code that you have to write.
One exceptions should be thrown that said, don't skip this homework.
It is important for understanding of the topic.
Thanks a lot for your attention.
See you in the next lesson.