From my understanding, Iterator enables you to go through elements of a Collection. I can understand its use and advantage for an interface that doesn t natively support a get(index) method, but how about for arrayList or Linkedlist?
As LinkedList (or ArrayList) already let me go through each element( with a for loop for example), why someone would still implement an Iterator?
Thanks.
Using the Iterator class when iterating a List is just one among a lot of ways to iterate lists. For an ArrayList it does exactly what you would do with a for loop, iterating with the use of indexes and get(index), just wrapped in the methods of Iterator and ArrayList. For inheritance reasons ArrayList has the functions implemented.
Related
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).
To remove element from ArrayList, we can use-
Iterator remove() is used while iteration.
For ArrrayList remove() no iteration required.
Syntax is different in those cases. So
Do both use same logic internally?
Is there any more difference than logic?
Which one is better?
Any detailed explanation/link is highly appreciated.
An iterator might throw ConcurrentModificationException if an element is removed from the underlying collection in another way than the iterator's own remove() method.
So if you need to remove elements while iterating over a collection, you're allowed to do that with Iterator.remove() but you can't do that with Collection.remove() without risking to get an exception.
remove is a method that should be implemented (if no, it should throw UnsupportedOperationException) by all objects that are Iterable (implement interface Itarable). The way it works depends always on the object that implements it.
That means an ArrayList can implement it in a totally different way then i.e. LinkedList.
Removing object in Iterator requires You to iterate (find) the object You want to remove.
Using a remove method in ArrayList (there is no delete I can see in Javadoc: http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html) finds the object for You and deletes it. It actually shifts objects in an underlying arrays to fill the "gap" You created by removing the object, so if You want to remove items in a list often, You could use LinkedList Instead.
Additionally while You are iterating through a list, You will cause an exception if You want to modify the collection in some other way than via iterator methods.
The exact answers to Your questions are:
1.No they use diferent logic, and additionally Iterator might even not allow to delete object (UnsupportedOperationException)
2.You cannot remove object by ArrayList remove while You are itereating, and to remove object at position 4 in ArrayList by using Iterator You would have to iterate 4 times "manually".
3.It depends whether You allready know what object do You want to remove, or first You check all the objects and decide whether to delete, during the iteration process. Additionally - If You want to delete objects often, You better use LinkedList, instead of ArrayList.
Iterator itr=al.iterator();
how does this line eactly work? does it just store the arraylist al in iterator? Can anyone pls give me a detailed explanation.
Thanks in advance.
From the documentation :
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.
http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html
Basically the iterator maintains a position for iterating over a collection. It can be used to iterate over a collection, with the option of modifying the collection while iterating over it without a ConcurrentModificationException.
Answer:
Returns an iterator over the elements in this list in proper sequence.
Before you can access a collection through an iterator, you must obtain one. Each of the collection classes provides an iterator( ) method that returns an iterator to the start of the collection. By using this iterator object, you can access each element in the collection, one element at a time.
I very much like the for-each-loop construction (for(T e : iterable)) in Java which works on any Iterable<T> because it makes in many cases very easy to read and to write code.
I wonder though if there is any way that I can access the underlying iterator from such a loop. This can be mandatory if I want to use the remove() from the iterator.
No, the whole point of the for-each-loop is to abstract away the underlying iterator.
If you need it, you must declare it.
No, you cannot remove objects in a for each loop.
Use this instead:
Iterator<Type> it = collection.iterator();
while (it.hasNext()) {
if (it.next().shouldBeRemoved()) {
it.remove();
}
}
Use a for loop instead.
If the collection is reasonably small, you can alternatively use a copy of the collection to iterate if you want to be able to remove elements so you won't have to act as if you have two collections.
for(T e : collection.clone())
if(e.shouldBeRemoved())
collection.remove();
Even better, Apache CollectionUtils (and there is probably a Google alternative and a generics alternative) provides filter(java.util.Collection collection, Predicate predicate). This example returns the whole list. You can store a predicate for reuse.
CollectionUtils.filter(collection, new Predicate(){
boolean evaluate(Object object){return true;}
});
You are correct, using an Iterator supports the ability to remove an object from a source collection safely, by calling remove() on the Iterator itself. The point here is to avoid a ConcurrentModifiedException which implies that a collection was modified while an Iterator was open against it. Some collections will let you get away with removing or adding elements to a Collection while iterating across it, but calling remove() on the Iterator is a safer practice.
But Iterator supports a derived and more powerful cousin ListIterator, only available from Lists, supports both adding and removing from a List during iteration, as well as bidirectional scrolling through Lists.
modifying data has a wrong feel to it, Just create a new Iterable(or collection) and add the items you want to keep to it, the other times are lost in the for loop ((kinda**
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/