What are the benefits of the Iterator interface in Java? - java

I just learned about how the Java Collections Framework implements data structures in linked lists. From what I understand, Iterators are a way of traversing through the items in a data structure such as a list. Why is this interface used? Why are the methods hasNext(), next() and remove() not directly coded to the data structure implementation itself?
From the Java website: link text
public interface Iterator<E> An
iterator over a collection. Iterator
takes the place of Enumeration in the
Java collections framework. Iterators
differ from enumerations in two ways:
Iterators allow the caller to remove
elements from the underlying
collection during the iteration with
well-defined semantics. Method names
have been improved. This interface is
a member of the Java Collections
Framework.
I tried googling around and can't seem to find a definite answer. Can someone shed some light on why Sun chose to use them? Is it because of better design? Increased security? Good OO practice?
Any help will be greatly appreciated. Thanks.

Why is this interface used?
Because it supports the basic operations that would allow a client programmer to iterate over any kind of collection (note: not necessarily a Collection in the Object sense).
Why are the methods... not directly
coded to the data structure
implementation itself?
They are, they're just marked Private so you can't reach into them and muck with them. More specifically:
You can implement or subclass an Iterator such that it does something the standard ones don't do, without having to alter the actual object it iterates over.
Objects that can be traversed over don't need to have their interfaces cluttered up with traversal methods, in particular any highly specialized methods.
You can hand out Iterators to however many clients you wish, and each client may traverse in their own time, at their own speed.
Java Iterators from the java.util package in particular will throw an exception if the storage that backs them is modified while you still have an Iterator out. This exception lets you know that the Iterator may now be returning invalid objects.
For simple programs, none of this probably seems worthwhile. The kind of complexity that makes them useful will come up on you quickly, though.

You ask: "Why are the methods hasNext(), next() and remove() not directly coded to the data structure implementation itself?".
The Java Collections framework chooses to define the Iterator interface as externalized to the collection itself. Normally, since every Java collection implements the Iterable interface, a Java program will call iterator to create its own iterator so that it can be used in a loop. As others have pointed out, Java 5 allows us to direct usage of the iterator, with a for-each loop.
Externalizing the iterator to its collection allows the client to control how one iterates through a collection. One use case that I can think of where this is useful is when one has an an unbounded collection such as all the web pages on the Internet to index.
In the classic GoF book, the contrast between internal and external iterators is spelled out quite clearly.
A fundamental issue is deciding which party conrols the iteration, the iterator or the client that uses the iterator. When the client controls the iteration, the iterator is called an external iterator, and when the iterator controls it, the iterator is an internal iterator. Clients that use an external iterator must advance the traversal and request the next element explicitly from the iterator. In contrast, the client hands an internal iterator an operation to perform, and the iterator applies that operation to every element ....
External iterators are more flexible than internal iterators. It's easy to compare two collections for equality with an external iterator, for example, but it's practically impossible with internal iterators ... But on the other hand, internal iterators are easier to use, because they define the iteration logic for you.
For an example of how internal iterators work, see Ruby's Enumerable API, which has internal iteration methods such as each. In Ruby, the idea is to pass a block of code (i.e. a closure) to an internal iterator so that a collection can take care of its own iteration.

it is important to keep the collection apart from the pointer. the iterator points at a specific place in a collection, and thus is not an integral part of the collection. this way, for an instance, you can use several iterators over the same collection.
the down-side of this seperation is that the iterator is not aware to changes made to the collection it iterates on. so you cannot change the collection's structure and expect the iterator to continue it's work without "complaints".

Using the Iterator interface allows any class that implements its methods to act as iterators. The notion of an interface in Java is to have, in a way, a contractual obligation to provide certain functionalities in a class that implements the interface, to act in a way that is required by the interface. Since the contractual obligations must be met in order to be a valid class, other classes which see the class implements the interface and thus reassured to know that the class will have those certain functionalities.
In this example, rather than implement the methods (hasNext(), next(), remove()) in the LinkedList class itself, the LinkedList class will declare that it implements the Iterator interface, so others know that the LinkedList can be used as an iterator. In turn, the LinkedList class will implement the methods from the Iterator interface (such as hasNext()), so it can function like an iterator.
In other words, implementing an interface is a object-oriented programming notion to let others know that a certain class has what it takes to be what it claims to be.
This notion is enforced by having methods that must be implemented by a class that implements the interface. This makes sure that other classes that want to use the class that implements the Iterator interface that it will indeed have methods that Iterators should have, such as hasNext().
Also, it should be noted that since Java does not have multiple inheritance, the use of interface can be used to emulate that feature. By implementing multiple interfaces, one can have a class that is a subclass to inherit some features, yet also "inherit" the features of another by implementing an interface. One example would be, if I wanted to have a subclass of the LinkedList class called ReversibleLinkedList which could iterate in reverse order, I may create an interface called ReverseIterator and enforce that it provide a previous() method. Since the LinkedList already implements Iterator, the new reversible list would have implemented both the Iterator and ReverseIterator interfaces.
You can read more about interfaces from What is an Interface? from The Java Tutorial from Sun.

Multiple instances of an interator can be used concurrently. Approach them as local cursors for the underlying data.
BTW: favoring interfaces over concrete implementations looses coupling
Look for the iterator design pattern, and here: http://en.wikipedia.org/wiki/Iterator

Because you may be iterating over something that's not a data structure. Let's say I have a networked application that pulls results from a server. I can return an Iterator wrapper around those results and stream them through any standard code that accepts an Iterator object.
Think of it as a key part of a good MVC design. The data has to get from the Model (i.e. data structure) to the View somehow. Using an Iterator as a go-between ensures that the implementation of the Model is never exposed. You could be keeping a LinkedList in memory, pulling information out of a decryption algorithm, or wrapping JDBC calls. It simply doesn't matter to the view, because the view only cares about the Iterator interface.

An interesting paper discussing the pro's and con's of using iterators:
http://www.sei.cmu.edu/pacc/CBSE5/Sridhar-cbse5-final.pdf

I think it is just good OO practice. You can have code that deals with all kinds of iterators, and even gives you the opportunity to create your own data structures or just generic classes that implement the iterator interface. You don't have to worry about what kind of implementation is behind it.

Just M2C, if you weren't aware: you can avoid directly using the iterator interface in situations where the for-each loop will suffice.

Ultimately, because Iterator captures a control abstraction that is applicable to a large number of data structures. If you're up on your category theory fu, you can have your mind blown by this paper: The Essence of the Iterator Pattern.

Well it seems like the first bullet point allows for multi-threaded (or single threaded if you screw up) applications to not need to lock the collection for concurrency violations. In .NET for example you cannot enumerate and modify a collection (or list or any IEnumerable) at the same time without locking or inheriting from IEnumerable and overriding methods (we get exceptions).

Iterator simply adds a common way of going over a collection of items. One of the nice features is the i.remove() in which you can remove elements from the list that you are iterating over. If you just tried to remove items from a list normally it would have weird effects or throw and exception.
The interface is like a contract for all things that implement it. You are basically saying.. anything that implements an iterator is guaranteed to have these methods that behave the same way. You can also use it to pass around iterator types if that is all you care about dealing with in your code. (you might not care what type of list it is.. you just want to pass an Iterator) You could put all these methods independently in the collections but you are not guaranteeing that they behave the same or that they even have the same name and signatures.

Iterators are one of the many design patterns available in java. Design patterns can be thought of as convenient building blocks, styles, usage of your code/structure.
To read more about the Iterator design pattern check out the this website that talks about Iterator as well as many other design patterns. Here is a snippet from the site on Iterator: http://www.patterndepot.com/put/8/Behavioral.html
The Iterator is one of the simplest
and most frequently used of the design
patterns. The Iterator pattern allows
you to move through a list or
collection of data using a standard
interface without having to know the
details of the internal
representations of that data. In
addition you can also define special
iterators that perform some special
processing and return only specified
elements of the data collection.

Iterators can be used against any sort of collection. They allow you to define an algorithm against a collection of items regardless of the underlying implementation. This means you can process a List, Set, String, File, Array, etc.
Ten years from now you can change your List implementation to a better implementation and the algorithm will still run seamlessly against it.

Iterator is useful when you are dealing with Collections in Java.
Use For-Each loop(Java1.5) for iterating over a collection or array or list.

The java.util.Iterator interface is used in the Java Collections Framework to allow modification of the collection while still iterating through it. If you just want to cleanly iterate over an entire collection, use a for-each instead, but a upside of Iterators is the functionality that you get: a optional remove() operation, and even better for the List Iterator interface, which offers add() and set() operations too. Both of these interfaces allow you to iterate over a collection and changing it structurally at the same time. Trying to modify a collection while iterating through it with a for-each would throw a ConcurrentModificationException, usually because the collection is unexpectedly modified!
Take a look at the ArrayList class
It has 2 private classes inside it (inner classes)
called Itr and ListItr
They implement Iterator and the ListIterator interfaces respectively
public class ArrayList..... { //enclosing class
private class Itr implements Iterator<E> {
public E next() {
return ArrayList.this.get(index++); //rough, not exact
}
//we have to use ArrayList.this.get() so the compiler will
//know that we are referring to the methods in the
//enclosing ArrayList class
public void remove() {
ArrayList.this.remove(prevIndex);
}
//checks for...co mod of the list
final void checkForComodification() { //ListItr gets this method as well
if (ArrayList.this.modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
}
private class ListItr extends Itr implements ListIterator<E> {
//methods inherted....
public void add(E e) {
ArrayList.this.add(cursor, e);
}
public void set(E e) {
ArrayList.this.set(cursor, e);
}
}
}
When you call the methods iterator() and listIterator(), they return
a new instance of the private class Itr or ListItr, and since these inner classes are "within" the enclosing ArrayList class, they can freely modify the ArrayList without triggering a ConcurrentModificationException, unless you change the list at the same time (conccurently) through set() add() or remove() methods of the ArrayList class.

Related

Are Java's collections interface and class hierarchy ill done?

I came to know that in Java, LinkedList class implements both Deque and List interfaces.
And this was somewhat confusing to me.
In computer science syllabus, I was never taught that queue can be a list, or more precisely queue can behave like a list. That is, there is stuff that lists can do, but queues can't. But the list can behave like a queue. For example, List interface has the following methods:
add(E e)
add(int index, E element)
But Queue has only the following:
add(E e)
So clearly Queue is not allowed to insert at specific index, which is allowed in List. The same is the case with other operations like Queue.remove() vs. List.remove(int index), List.get(int index) vs. Queue.peek().
In other words, list is a more generalized data structure and can emulate Queue.
Now being capable to emulate is different from having a contract subset. That is, Queue disallows certain operations (indexing) of Listand allows certain operations done only in a particular manner (insert only at the tail and remove only from the head). So Queue does not really do "addition" to the contracts of List. That is precisely why Queue does not extend List in Java collections framework, but both extend Collection interface. I believe that is also why it's incorrect for any class to implement both, as Queue's contract conflicts with the contract of List (which is why they fork out from Collection interface separately). However, LinkedList implements both the interfaces.
I also came across this answer:
The LinkedList implementation happens to satisfy the Deque contract, so why not make it implement the interface?
I still don't get how we can say "LinkedList implementation happens to satisfy the Deque contract". The concept of a queue does not allow insertion at an arbitrary index. Hence, the Queue interface does not have such methods.
However we can only enforce contracts through interfaces and cannot disallow implementation of certain methods. Being list (having "List" in its name), I feel it's not correct to have queue methods peek(), pop() and add(int index, E element) in LinkedList.
I believe, instead we should have separate class LinkedQueue which can have linked implementation for queue, similar to LinkedBlockingQueue which contains linked implementation of BlockingQueue.
Also note that LinkedList is the only class which inherits from both families of lists and queues, that is, there is no other class which implements both List and Queue (AFAIK). Can this be indication that LinkedList is ill done?
Am I plain wrong and thinking unnecessarily?
You're entirely missing the point of programming to interface.
If you need a Queue, you never write:
LinkedList<String> queue = new LinkedList<>();
Because, you're right, that would allow you to use non-queue methods. Instead, you program to the interface like this:
Queue<String> queue = new LinkedList<>();
Now you only have access to the 6 Queue methods (and all the Collection methods). So, even though LinkedList implements more methods, you no longer have access to them.
So, if you need a Queue, you choose the implementation of the Queue interface that best suits the performance, storage, and access characteristics you need, e.g.
LinkedList uses more memory, but it shrinks when queue is emptied.
ArrayDeque uses less memory, but it doesn't shrink.
PriorityQueue is a non-FIFO queue with element priority.
ConcurrentLinkedQueue, ConcurrentLinkedDeque supports multi-threaded concurrent access.
and more...
I was never taught that queue can be a list, or more precisely queue can behave like a list.
Remember that implements defines a behaves like relationship. A LinkedList behaves like a List. A LinkedList behaves like a Deque. A LinkedList behaves like a Queue.
But just because LinkedList behaves like all of those, doesn't mean that List behaves like a Queue or that Queue behaves like a List. They do not.
The behaves like relation only goes one way.
#Andreas's answer is excellent, so mine targets your arguments about what you were or were not taught:
In computer science syllabus, I was never taught that queue can be a list or more precisely queue can behave like a list
A queue is not just any list, but a special kind of list, with its own special properties and constraints.
That is, there is stuff that lists can do, but queues can't.
No, List can do nothing. It provides possibilities to be implemented by a class and if that class decides to implement them then that class can do all that stuff.
But the list can behave like a queue.
No, List does not behave; it only suggests behaviors and classes that implement it can accept all or a subset of them or they can define new ones.
LinkedList is a class that implements both List and Deque interfaces. Each one of these interfaces defines a contract with operations, and in these contracts it is specified what these operations must do. However, it is not specified how these operations are supposed to work.
LinkedList is a class that implements both List and Deque interfaces. So, despite the suffix List is part of the name of the LinkedList class, LinkedList is actually both a List and a Deque, because it implements all of the operations that are defined in the List and Deque interfaces.
So LinkedList is a a List, and it also is a Deque. This doesn't mean that a List should be a Deque, or that a Deque should be a List.
For example, look at the following interfaces:
public interface BloodDrinker {
void drinkBlood();
}
public interface FlyingInsect {
void flyAround();
}
Each one of the interfaces above has a single operation and defines a contract. The drinkBlood operation defines what a BloodDrinker must do, but not how. Same applies for a FlyingInsect: its flyAround operation defines what it must do, but not how.
Now consider the Mosquito class:
public class Mosquito implements FlyingInsect, BloodDrinker {
public void flyAround() {
// fly by moving wings,
// buzzing and bothering everyone around
}
public void drinkBlood() {
// drink blood by biting other animals:
// suck their blood and inject saliva
}
}
Now, this means that a Mosquito is both a FlyingInsect and a BloodDrinker, but why would a blood drinker necessarily be a flying insect, or a flying insect necessarily be a blood drinker? For example, vampires are blood drinkers, but not flying insects, while butterflies are flying insects, but not blood drinkers.
Now, with regard to your argument about Queue disallowing certain List's operations (indexing), and only allowing addition/removal on its ends in a FIFO fashion... I don't think this rationale is correct, at least in the context of the Java Collections Framework. The contract of Deque doesn't explicitly mention that implementors will never ever be able to add/remove/check elements at any given index. It just says that a Deque is:
A linear collection that supports element insertion and removal at both ends.
And it also says that:
This interface defines methods to access the elements at both ends of the deque.
(Emphasis mine).
A few paragraphs later, it does explicitly say that:
Unlike the List interface, this interface does not provide support for indexed access to elements.
(Emphasis mine again).
The key part here is does not provide support. It never forbids implementors to access elements via indexes. It's just that indexed access is not supported through the Deque interface.
Think of my example above: why would a BloodDrinker disallow its implementors to drink something other than blood, i.e. water? Or why would a FlyingInsect disallow its implementors to move in a way different than flying, i.e. walking?
Bottom line, an implementation can adhere to as many contracts as it wishes, as long as these contracts don't contradict each other. And as it's worded in Java (a very careful and subtle wording, I must admit), Deque's contract doesn't contradict List's contract, so there can perfectly exist a class that implements both interfaces, and this happens to be LinkedList.
You are starting from a weak premise:
I was never taught that queue can be a list.
Let us go back to the basics. So what are data structures anyway? Here is how CLSR approaches that question1:
...Whereas mathematical sets are unchanging, the sets manipulated by
algorithms can grow, shrink, or otherwise change over time.
Mathematically, data structures are just sets; dynamic sets. In that sense, a queue can be a list. In fact, there is a problem in CLSR (10.2-3) that explicitly asks you to implement a queue by using a linked list.
On the other hand, object-oriented programming is a paradigm that helps programmers solve problems by adhering to a certain philosophy about the problem and the data. Objects, interfaces, and contracts are all part of this philosophy. Using this paradigm helps us implement the abstract concept of dynamic sets. However, it comes with its own baggage, one of them being the very problem asked about here.
So if you are complaining that the data structures in Java standard library do not strictly adhere to the conventions defined for elementary data structures, you are right. In fact, we do not even need to look further than java.util.Stack to see this2. You are also allowed to roll out your own implementation in any way you want and use them instead of standard library collections.
But to argue that Java, or its standard library for that matter, is broken or ill-done - an extraoridnary claim- you need to be very specific about the use case and clearly demonstrate how the alleged flaw in the library prevents you from achieving the design goals.
1 Introduction to Chapter III, p220
2 Sedgewick and Wayne call java.util.Stack a "wide interface"(p 160) because it allows random access to stack elements; something a stack -as defined in elementary data structures- is not supposed to be capable of.
You are entirely correct in this and not missing the point at all. Java simply made a trade-off between correctness and ease. Making it implement both interfaces was the easy thing to do and the one that was the most useful for developers.
What subtyping means
Correct (sound) subtyping requires substitution to work which requires according to the LSP:
Invariants of the supertype must be preserved in a subtype.
When we say in type theory "A LinkedList is a List and a Queue" we are actually saying that a LinkedList is both a list and a queue at the same time and not that a LinkedList can be thought of as either a list or a queue.
There is a violated invariant of a queue type here (that you cannot modify elements in its middle) so it is incorrect subtyping.
The actual argument that should be had is "whether or not a queue requires that elements can't be modified in the middle or only that they can be modified in the ends in FIFO".
One might argue that the invariants of a Queue are only that you can use it in a FIFO matter and not that you must. That is not the common interpertation of a queue.

How do I find the implementation of the abstract method, hasNext()?

I'm confused about the following situation related to Java OOP and Java API/source code arrangement. Based on Oracle's Java 8 API, hasNext() is an abstract method, but I couldn't find where hasNext() is implemented. I read that private inner classes are used to implement different Iterators in each Collection class, but there is no more info about how to find the location of the implementation. Some users suggested me to add Java JRE 1.8 source code to my Eclipse IDE, but I can only see boolean hasNext(); declared as an abstract method in the Iterator interface.
As the example shown below, the iterator obj uses hasNext() directly w/o implementing it. However, I was taught you need to implement an abstract method in an interface.
My Question:
(1) How do I find the implementation of the abstract method, hasNext()?
(2) A comment says I can find the code here. What's the reason to implement hasNext() in ArrayList class, but mark hasNext() as an abstract method? It is not intuitive to find the hasNext() implementation this way.
List<String> list = new ArrayList<String>();
list.add("item-1");
list.add("item-2");
list.add("item-3");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
You can see in your code, that List is an ArrayList. The method in ArrayList called iterator() will return an implementation of Iterator. This implementation of Iterator will have the method hasNext() implemented.
It's great to be curious, and as the comment said, you can click into the code in an IDE (or if that doesn't work for you, set a break point in a debugger and step in). Reading the Java code is a great way to de-mystify it.
Of course, you can generally can expect the Java people to know what they are doing, and trust the implementations you get back to be sensible, and fit for general use. The caveat here is that you should also read the documentation. eg. from https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
The iterators returned by this class's iterator and listIterator
methods are fail-fast: if the list is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException. Thus, in the face of concurrent
modification, the iterator fails quickly and cleanly, rather than
risking arbitrary, non-deterministic behavior at an undetermined time
in the future.
An iterator over a collection. Iterator takes the place of Enumeration in the Java Collections Framework. Iterators differ from enumerations in two ways:
Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
Method names have been improved.
https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html
I was having the same question If ListIterator is interface which contains only abstract method which class is responsible for the implementation those methods.
arrived on the conclusion (correct me if I'm wrong)
ArrayList instance method ListIterator is returning instance of ListItr(0)
ListItr(java.util.ArrayList.ListItr) is the class which is implementing the ListIterator interface with the implementation of the abstract methods.
Technically ListIterator can hold instance of it's implementation class.
The next() and hasNext() methods are part of the Iterator interface. Each specific implementation will provide their own versions. You can take a look at how they are defined for the ArrayListIterator in the commons-collection library here or SingletonListIterator here.

Why don't we put the hasNext(), next() and other methods in Collection interface?

I am confused with a design problem in Java. It realized many abstract containers under the interface Collection and provides the method hasNext() and Next() along with class Iterator. What is the drawback if I put these methods directly under interface Collection and then overrides it in each subclass:
For example, I have already realized Next(); hasNext() method under class ArrayList. So what I wrote is
ArrayList ArrList=new ArrayList()
if(ArrList.hasNext())
new obj=ArrList.next();
}
returning the objects stored in ArrList.
So is it redundant to introduce Iterator class for the interface Collection? And what is the benefit to design ArrList.iterator(); if it's more covenient to set it up in interface?
Can I find any book to solve such oop-design problems(As the computer scientists described it)?
Thanks for your time.
The methods of the Iterator interface (next(), hasNext()) can't simply be added to the interface. An Iterator has a state which determines the next element that would be returned by the iterator.
If the Iterator methods were part of the Collection interface, you would need some additional method to reset this "built-in" iterator (in order to iterate again from the start of the Collection), and you would only have a single iterator for each Collection in any given time. A nested iteration as simple as the following snippet wouldn't be possible, since it requires two iterators :
List<Integer> list = ...
for (int i : list)
for (int j : list)
System.out.println(i+j);
Iterator stores a pointer to some element inside a collection. In case of ArrayList it is an index of the underlying array.
It allows you to say iterate over the collection in two separate threads simultaneously. If the pointer was a part of ArrayList, each of the threads would skip some of the elements.
An iterator is usually made to traversed once. In the Java collection library classes will fail if modifications are made to the underlying collection during a traversal of an iterator.
BTW, this question may be more appropriate for Programmers Stack Exchange which is dedicated to theoretical programming questions.
Let's assume for a moment that ArrayList did have hasNext and next methods, and so your code would compile. (You'd also need another method to tell the list you wanted to start over again.) That would mean that I could only have one iteration of the list active at a time, because the list itself contains the iteration state. That's just poor design; instead, we have the Iterator concept so that the state of the iteration is stored in the iterator, not the list, and we can have multiple iterators.
At the conceptual level: Collection represents a collection of objects. Adding methods for hasNext and next would turn it into a collection of objects along with another piece of state, a 'current object', as well as some concept of how to traverse the collection.
Since these are two separate ideas, it is best to divide them into separate structures that are implemented independently. In the case you speak of, that would be the Collection structure (which handles storage and structure for a collection of objects), and the Iterator structure (which handles position and traversal of some collection of objects).

Enforcing order in Java Iterator

I am providing a library for a different team. One of the methods I provide receives as argument an Iterator. I would like to somehow require a certain order of iteration. Is there any way to do this in code by extending Iterator?
Not directly. The iterator is made just to give you an item at time, avoiding to storing in memory and pass a whole list of values, which could be unfeasible at times.
Unless you have more knowledge on how the values are generated and which bounds have to be applied to the sorting of data, the only way is to get all elements from the iterator, store them in some list/vector/database, sort them and return another iterator using the sorted list.
You're being passed, as an argument, an instance of some concrete class which implements Iterator. You can't extend its class because its class is decided upon instantiation, which is done by the code that calls your method.
If you want to fail fast when the required order is not respected, try Guava's Ordering.isOrdered() method.
NB This will only work if your argument is an Iterable, rather than Iterator. You need it to be Iterable (an interface which allows you to retrieve the Iterator) so that you can iterate twice: once to check order, once to process.

What is the Iterable interface used for?

I am a beginner and I cannot understand the real effect of the Iterable interface.
Besides what Jeremy said, its main benefit is that it has its own bit of syntactic sugar: the enhanced for-loop. If you have, say, an Iterable<String>, you can do:
for (String str : myIterable) {
...
}
Nice and easy, isn't it? All the dirty work of creating the Iterator<String>, checking if it hasNext(), and calling str = getNext() is handled behind the scenes by the compiler.
And since most collections either implement Iterable or have a view that returns one (such as Map's keySet() or values()), this makes working with collections much easier.
The Iterable Javadoc gives a full list of classes that implement Iterable.
If you have a complicated data set, like a tree or a helical queue (yes, I just made that up), but you don't care how it's structured internally, you just want to get all elements one by one, you get it to return an iterator.
The complex object in question, be it a tree or a queue or a WombleBasket implements Iterable, and can return an iterator object that you can query using the Iterator methods.
That way, you can just ask it if it hasNext(), and if it does, you get the next() item, without worrying where to get it from the tree or wherever.
It returns an java.util.Iterator. It is mainly used to be able to use the implementing type in the enhanced for loop
List<Item> list = ...
for (Item i:list) {
// use i
}
Under the hood the compiler calls the list.iterator() and iterates it giving you the i inside the for loop.
An interface is at its heart a list of methods that a class should implement. The iterable interface is very simple -- there is only one method to implement: Iterator(). When a class implements the Iterable interface, it is telling other classes that you can get an Iterator object to use to iterate over (i.e., traverse) the data in the object.
Iterators basically allow for iteration over any Collection.
It's also what is required to use Java's for-each control statement.
The Iterable is defined as a generic type.
Iterable , where T type parameter represents the type of elements returned by the iterator.
An object that implements this interface allows it to be the target of the “foreach” statement. The for-each loop is used for iterating over arrays, collections.
read more -: https://examples.javacodegeeks.com/iterable-java-example-java-lang-iterable-interface/

Categories