H2ONaCl
H2ONaCl

Reputation: 11269

How to get the Collection of an iterator in Java?

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.

Upvotes: 1

Views: 5481

Answers (3)

Ray Toal
Ray Toal

Reputation: 88378

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.

Upvotes: 1

Bruno Reis
Bruno Reis

Reputation: 37822

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.

Upvotes: 11

neodelphi
neodelphi

Reputation: 2786

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 !

Upvotes: 0

Related Questions