Implementation of Iterator methods - java

I am working with collections. One thing which is bothering me is: where is the Implementations of the methods of java.util.Iterator Interface? In which class these methods are implemented?
public abstract boolean hasNext();
public abstract E next();
public abstract void remove();
I searched the source code of the java API, but didn't find the implementation of these methods in any class.

Iterator is an interface and it has around 50 implementations in the java api itself.
Since the iterator needs to compy with the iterating object type, for ex if you want to iterate an ArrayList the iterator instance which your iterator() method returns is of new Itr type. see the implementation in java.util.AbstractList class which forms the base class for ArrayList

There are multiple classes in JDK where It has been implemented. ArrayList is very good example for your concern. You can go through the code in openJDK. And the iterator method defination is -
public Iterator<E> iterator() {
return new Itr();
}
Where This Itr private class implements Iterator<E> and define all itarator method.

You can search java apis who implements Iterator. Those classes all have implements the above methods. Go to browse the jdk source code. It will help you a lot.

In case you are using eclipse and you have source code configured in eclipse itself.
Just select the method and press Ctrl + T (show type hierarchy) and you can see all the classes in which the method has been implemented.

Related

Where are the methods of the Iterator Interface actually implemented in the Collections Framework?

Following the hierarchy of the Collections Framework in Java, I struggle to understand where these 2 methods of the Iterator Interface are being implemented.
boolean hasNext();
E next();
The other 2 methods
default void remove()
default void forEachRemaining(Consumer<? super E> action)
have default implementations in the Iterator Interface itself (although they are probably overridden somewhere else too).
image source: https://www.javatpoint.com/collections-in-java
I know that depending on the hierarchy, for example Interface -> Interface -> Class, the implementation can be either in the interface itself as a default method or in the concrete class. But lets take for example the ArrayList, where in the whole hierarchy are the hasNext() and next() methods being implemented.
Collection implements Iterable and Iterable has the method iterator() that returns the Iterator interface, so implementations dont have to implement the Iterator interface.
If you take ArrayList for example, it inherits AbstractList which implements iterator and that is used by different lists implementations.

Iterable and Iterator in java

Here is my understanding on significance of using Iterable and Iterator in pre 1.8 java.
1)
java.util.AbstractList is Iterable because it implements,
Iterator<T> iterator();, which is a contract for any class to be Iterable.
2)
java.util.AbstractList implements,
Iterator<T> iterator(); by creating an instance level inner class,
private class Itr implements Iterator<E> { ... }
that implements hasNext, next and remove methods.
private class ListItr extends Itr implements ListIterator<E>{..} is just an extra facility over above iterator for List type implementations.
3)
Is this the only purpose of these two interfaces Iterable & Iterator, to enable any object to be iterable? Please let me know, if there is any other purpose of these two interfaces?
You are right stating what these interfaces are used for. Indeed Iterable declares that the objects of a class implementing it may be iterated over, by providjng an Iterator specific to these objects. Having them is necessary because how exactly the object should be iterated depends on its internal implementation, and an Iterator is therefore specific to a given "collection" class.
Having said that, it is worth noting that although these interfaces are formally a part of Java Collections framework, they can be applied to other cases. Given an imaginary API to read CSV files for example, one can declare a CsvFile class to implement an Iterable<List<String>> and iterate over lines in a file with a dedicated Iterator<List<String>> which will read lines from the file one-by-one and split them into a List of Strings to return it from next().
Another important purpose of these interfaces is a language feature known as "for each" loop - only objects of a class implementing Iterable can be iterated with it. So, given an example from above about CsvFile API, it will also enable something like:
CsvFile csvFile = new CsvFile(pathToCsvFile);
for (List<String> record : csvFile) {
doSomethingWithIt(record);
}
As "for each" loop is purely a language feature, compiler will expand it to use an Iterator as usual.
P.S. Just because it hurts my eyes, I'd like to add that in the example above I would also suggest implementing an AutoCloseable for the CsvFile and using it with try-with-resources.
java.util.Collection interface extends to java.util.Iterable. Iterable has a method that produces the iterator. If any class implements iterable, it has an iterator method that produces java.util.Iterator.
Please refer to this post
If you check out interface Iterable it has only one method that is Iterator<T> iterator();. So there is no other possible use case for implementing Iterable interface other than providing iterator method.
If you see the documentation of Iterator interface, in See Also section you will find Collection, ListIterator, Iterable. Collection and ListIterator are by default Iterable as they internally extend Iterable. So Iterable is used in conjunction with Iterator.

Where is the iterator interface implementation in Java 5 and above?

As Iterator is an interface with hasNext(), next() and remove() methods. But where is the implementation for all these methods in Java classes?
Almost every concrete collection has its own implementation, optimized for that specific collection. You don't have to bother about the details. But here are some examples:
LinkedList - class ListItr implements ListIterator<E>
ArrayList - class ListItr extends Itr implements ListIterator<E>
HashSet - actually backed by HashMap.keySet()
Becasue Iterator is an interface, you can do fancy things with it, like wrapping and decorating it, without paying attention to the actual implementation.
The Iterator interface is implemented as a inner and private (should be but not necessarily) class in the class/interface that implements the java.lang.Iterable<T> interface. The method of Iterable<T> - Iterator<T> iterator() allows an object to be the target of the "foreach" statement.
For more information read the blog of #Andreas Grech : Java's Iterators and Iterables

How does Iterator ties into Collection Interface

I am new to Java.
Java has Collection interface
public interface Collection<E> extends Iterable<E>
{ // a lot of other stuff.
Iterator<E> iterator(); }
What I don't understand is how does Iterator Interface is tying into Collection Interface ? When I look at the Collection Interface, I see that it has a method that returns Iterator. When Iterator for Collection is created, where does JVM looks to create an object that IS-An Iterator ?
Thanks !
The JVM doesn't do it; the code that ultimately implements the abstract iterator() method just creates an instance of an appropriate class and returns it. For example, in the class ArrayList(), which implements List which extends Collection, there is a method that implements iterator() by returning an instance of a class that understand how ArrayList is implemented internally. This Iterator class is private to the java.util package -- normally you'll never see its name.
Ok so this is all pretty advanced java stuff and it will be pretty tough to explain in one go here but I will do my best.
BACKGROUND: If you don't know about those funny <E> things, you should do a bit of looking into Java Generics. Also, if you don't already, you really need to know what an interface is. One really basic way to think of it is as a promised bit of functionality a class promises to provide.
Now to answer your question: There are three interfaces in the above code snippet, and if you want to create your own collection class you will need to provide implementations of all three:
The first is Collection. This is a simple concept that maps to the real world, it is literally a "collection" of objects. I think you get this...
The next one is Iterable this defines a singe type of behavior that all collections need to provide: the ability to traverse all of the elements of a collection, while accessing them one by one ie "iterate" over them. But it doesn't stop there. As you pointed out the Iterable functionality is provided by objects that implement the last interface:
Iterator: objects that implement this interface, actually know how to traverse the elements of a collection class, they hide all the details of how its actually done from thier clients and proved a few clean easy methods for actually doing it like hasNext() which checks to see if there are more things in the collection to visit and next() which actually visits the next thing.
phew...
The code for the iterator() method determines which concrete implementation of Iterator to return.
All non-abstract classes that implement the Collection interface are required to provide an implementation for the iterator() method.

java implementing an interface with additional methods

I have a class MyDoublyIterator<E> that implements the Iterator<E> interface. Also, it has a couple other methods not part of the interface (for example public void boolean hasPrev()). When I try to call that method in my main class my IDE can't resolve that method.
Here's the code I'm using to call it
Iterator<String> di = new MyDoublyIterator<String>();
di.hasPrev();
So I guess my question why can't it find that method. Do I have to build an abstract class that implements the interface and extend it?
The Problem is that the di-variable is of the type Iterator. So it could contain any implementation of this interface. And therefore the IDE cannot be sure that it contains an instance of MyDoublyIterator. So to make it work like you requested, you have to change the type of the variable to MyDoublyIterator.
It is better to first extend the original interface Iterator<E> with your own interface eg: DoubleIterator<E> with additional methods like hasPrev() and then implement the newly created interface DoubleIterator<E> in your class MyDoublyIterator<E>.
Otherwise you can instantiate your class like this:
MyDoublyIterator<String> di = new MyDoublyIterator<String>();
di.hasPrev();
Then compiler won't complain since you are creating a type of MyDoublyIterator<E>.
When compiler sees di.hasPrev(); It only knows that di is Iterator<String> and has no clue that it's your own type. So it is not aware of your custom methods.
Iterator<String> di = new MyDoublyIterator<String>();
di.hasPrev();
It won't help you. Compiler needs a way to know that your own interface has that method, and not the built-in interface Iterator interface i.e Iterator<String>. Here, you are creating a reference for the built-in Iterator interface i.e Iterator<String>.
Hence, if you have your own interface named MyDoublyIterator<E> and this interface has the method named hasPrev(); you need to do this :
MyDoublyInterface<String> di = new MyDoublyIterator<String>();
di.hasPrev();
and then it will resolve the method call, since it knows that you have created a reference of your own MyDoubleInterface<T> and it should solve the problem now. :-)
Other answers are correct, but here's another spin - create an interface that extends Iterator:
interface DoublyIterator<E> extends Iterator<E> {
boolean hasPrev();
}
class MyDoublyIterator<E> implements DoublyIterator<E> {
// ... implement methods
}
DoublyIterator<String> di = new MyDoublyIterator<String>();
di.hasPrev();

Categories