When would it be useful to implement iterator without implementing iterable?
Or is implementing iterator simply a by product of implementing iterable?
These two are related but not the same.
A List is Iterable - you can get its Iterator. It is not an Iterator.
An Iterator is a single use class that can iterate along a Collection of objects using the hasNext and next methods.
An Iterable is a Collection class that returns an Iterator instance when then the iterator() method is called.
I would go as far as to say that I see no case where an Iterable should implements Iterator. And as a Iterator is single use I cannot see a case where Iterator should implements Iterable.
Generally speaking, you'd implement either an Iterable or an Iterator to hide the implementation of a collection from the code that's iterating over the collection. Either one would work well. The difference lies in how many times the collection can be traversed. An iterator can only traverse the collection once while the Iterable can traverse the collection many times. You can traverse the Iterable by asking it for an Iterator and you can do that multiple times.
They are very similar in semantics and use cases, but differ in implementation. Iterable is a simple factory for Iterators which can be used inside for loops. For this reason it's might be more convenient to implement an Iterable.
for(String s : getIterable()){
...
}
Versus:
Iterator<String> it = getIterator();
while(it.hasNext()){
String s = it.next();
...
}
However, in some case Iterator might not be re-instantiated, i.e. when you're running through a db request results, so in this case you can't make it Iterable without re-sending your request.
Related
List<String> stringList;
//fill with strings somehow
Collection<String> stringCollection = (Collection<String>) stringList;
for(String str : stringCollection){
//will this loop be guaranteed to iterate in the order found in stringList
}
I think it is guaranteed that this for-each loop will iterate in the correct order, since the syntactic sugar actually uses an iterator and the iterator() method is overridden in List to have an order. Since the run time type of stringCollection is a List, then it will use the overridden method which starts at the beginning of the list. Is this correct?
Yes, the enhanced for loop will use the iterator of the provided collection. So if b is really a list (runtime type), then the order will be guaranteed.
Note that with the new stream API (Java SE 8) this is a little bit different.
While b.stream() would still guarantee the order, b.parallelStream() wouldn't.
Also see: https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#ordering
http://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#iterator()
Returns an iterator over the elements in this collection. There are no
guarantees concerning the order in which the elements are returned
(unless this collection is an instance of some class that provides a
guarantee).
Yes.
Collection.iterator is implemented by the JDK implementations of Collection, like ArrayList. This is inherent to how object oriented programming works; if you call a method of an object where you only know one of it's interfaces, it will still call the method of the fully implemented class.
Neither the Collection nor List interface provide an implementation for the iterate() method, so this implementation must come from the run-time type of the object you're iterating over. So yes, the collection will iterate in a predictable order if you use an ordered list.
The Enumeration interface of java has 2 methods
hasNext()
next()
Why doesn't Iterator extend Enumeration and add the remove method()?
Also, if all I want to do is loop over my collection, I can make do with an Enumeration (or an iterator if it extends enumeration) as loop statements only need an enumeration. I don't have to worry about the collection getting modified
Why doesn't Iterator extend Enumeration and add the remove() method?
From the documentation:
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.
I suspect the latter is the real reason for introducing a brand new interface instead of extending the existing one.
Also, if all I want to do is loop over my collection, I can make do with an Enumeration (or an iterator if it extends enumeration) as loop statements only need an enumeration. I don't have to worry about the collection getting modified
Well, if you don't want to modify the collection, then don't call remove(). If you really, really don't trust yourself, you could use Collections.unmodifiableCollection() et al to create a read-only wrapper.
Finally, it is worth noting that if you use a for-each loop to iterate over the collection, you don't have access to the remove() method anyway:
for (String s : str_list) {
...
}
Here, we are using the Iterator interface, but don't have access to the actual iterator object.
You could just obtain a java.util.Enumerator from your collection, via the java.util.Collections.enumeration() Method.
Anyway, if you don't want to modify your collection via its iterator, it's just a matter of not calling the remove() method.
According to http://www.journaldev.com/1330/java-collections-interview-questions-and-answers#iterator-vs-enumeration, "Enumeration is twice as fast as Iterator and uses very less memory. Enumeration is very basic and fits to basic needs."
So, I guess if you don't need remove(), then using Enumeration is more effective than using Iterator.
Is there any way to convert an object of LinkedList class to a circular linked list.
Or is there any predefined class like CircularLinkedList in java.util
Some thing like this (some thing like http://docs.oracle.com/javase/1.4.2/docs/api/java/util/LinkedList.html)
Any help would be really appreciated....
Thanks in Advance :-)
No, the LinkedList is encapsulated in a way which makes it impossible to connect its tail to its head. I don't think that any of the default collections supports that, because then it wouldn't fulfill the contract for Iterable anymore, which says that an iterator got to get to the end sometime.
When you need a data structure like that, you have to implement it yourself.
Have a look at Guava's Iterables.cycle method.
public static <T> Iterable<T> cycle(Iterable<T> iterable)
Returns an iterable whose iterators cycle indefinitely over the elements of iterable.
That iterator supports remove() if iterable.iterator() does. After remove() is called, subsequent cycles omit the removed element, which is no longer in iterable. The iterator's hasNext() method returns true until iterable is empty.
Refer doc : http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterables.html#cycle%28java.lang.Iterable%29 .
Often there is the need to setup an ArrayList<>. One of the constructors takes a collection, but there is no constructor that takes an iterator.
What if I have an iterator? Is there a way to "reach up" to the collection that offers the iterator in order to use the ArrayList<> constructor?
Specifically I have the iterator offered by PropertiesConfiguration.getKeys() which is part of org.apache.commons.
There's no such thing, an Iterator's Collection. An Iterator can be created independently of a Collection. It can be obtained from any Iterable, or you can even create a class implementing an iterator.
However, you can obtain an ArrayList from an Iterator by iterating it and adding its elements one by one:
Iterator<X> it = ...;
List<X> list = new ArrayList<X>();
while (it.hasNext()) {
list.add(it.next());
}
Note, however, that this cannot be done reliably for every possible iterator, since there's the possibility that an iterator will iterate forever, thus causing an infinite loop and most probably an OutOfMemoryError.
I'd suggest you take a look at Google Guava, an utility library from Google. It has a class called Lists, which allows you to do the following:
Iterator<X> it = ...;
List<X> list = Lists.newArrayList(it);
The library has tons of methods extremely useful for everyday Java coding. It contains mostly everything you want but cannot find in the standard Java 6 API.
There is no truly general way to do this, because in Java, Iterator is just an interface with three methods: next, hasNext and remove.
When you obtain an iterator, you use a factory method that gives you an instance of some class implementing the interface. If you know the specific class, you can look at its documentation or source to find if there is a way to find the collection it is iterating over.
But there are many such classes. In the case of ArrayList, look in the source code to see what kind of iterator you are getting.
EDIT:
Here is the source code for ArrayList in Open JDK 7: http://www.docjar.com/html/api/java/util/ArrayList.java.html
The iterator over an ArrayList is an instance of the private inner class Itr. This should not be too surprising. The iterator comes from a factory method, after all, so you're really not supposed to know what kind of iterator you are getting. In fact, if you were able to get the class of this instance and access its methods (say, via reflection) you would be doing a bad thing. This iterator is part of the (internal) implementation of the ArrayList class and (as #merryprankster points out) can change in the future.
I don't know if its possible, but in my opinion, a such function should not exist because an iterator may not come from a collection. For example, one could create an iterator which chains over multiple collections !
What is Iterator and collections?
Does these two have any relations?
// the interface definition
Interface Iterator {
boolean hasNext();
Object next(); // note "one-way" traffic
void remove();
}
// an example
public static void main (String[] args){
ArrayList cars = new ArrayList();
for (int i = 0; i < 12; i++)
cars.add (new Car());
Iterator it = cats.iterator();
while (it.hasNext())
System.out.println ((Car)it.next());
}
Does the Interface Iterator has these method names alone predefined or its user defined?.
What does these four lines below actually tell?
cars.add (new Car());
Iterator it = cats.iterator();
while (it.hasNext())
System.out.println ((Car)it.next());
Thanks. I am going through a book in collections.
The Java collections are, as the name says, collections of things. If you don't know that word, look it up in a dictionary.
There are many types of collections. Take for example the mathematical concept of a set. You can put arbitrary things in a set, but it will never contain the same thing more than once. The things in the set are not ordered, that is you cannot say A comes before B. Another type of collection is a list. A list can contain the same thing more than once, and the order of the things in the list is important.
What all these collections have in common is that they contain things, which in Java are called elements. When you want to know which things are in a certain collection, you iterate over the collection, which is just another term for going through all elements. This is what an Iterator does. It basically starts at the beginning of a collection, you can always ask whether there is a next element (hasNext()), and if there is, you can get access to that element (next()), until you have iterated over all elements in the collection.
Technically iterators and collections are not directly related. However Iterators are mostly used together with collections to interate over the objects contained in the collection.
Iterators are a general and flexible concept that allows to interate objects without depending on the exact implementation of the entity that they iterate over.
An iterator is most commonly used as a mechanism for going through the elements of a collection.
The concept is not specific to Java at all, though the specific interface definition you show is.
See the Wikipedia article on Iterator for some discussion of what it means and how it's done in assorted languages including Java.
In Java, it is an Interface, so you can indeed implement your own, but sensible ones are defined for the collections in Java's collections library and for any Java Collection implementation the method
collection.iterator()
should return an iterator that will traverse the elements of that collection.
Also see the javadoc for Collection and Iterator for more.