List or Iterator

A

Adam Lipscombe

Folks


Are there any advantages in speed in passing a List or an Iterator as a method parameter, or as a method return value?
Any runtime reasons why one should be preferred over the other?

Thanks - Adam
 
L

Lew

Adam said:
Are there any advantages in speed in passing a List or an Iterator as a
method parameter, or as a method return value?
No.

Any runtime reasons why one should be preferred over the other?

Yes. Also design reasons.

Iterators don't like to share. Using one as a method parameter risks
ConcurrentModificationException.

It makes perfect sense to return an Iterator if the purpose of the method is
to obtain an iterator. Such a method should be an instance method of an
'Iterable' object.

It makes little if any sense to return an iterator that is not clearly tied to
such an object. Oh, I suppose one could manufacture a use case for such a
thing, but it would be at best a corner case, or else some sort of low-level
private or package-private implementation mechanism. Typically one would want
to return an 'Iterable' (which is therefore amenable to for-each looping) or
similar.

Iterators are by nature transitory, local things. Passing them around
willy-nilly will lead to bugs.
 
E

Eric Sosman

Adam said:
Folks


Are there any advantages in speed in passing a List or an Iterator as a
method parameter, or as a method return value?

Nothing known to me, and if there's any difference at all
I'd expect it to be so small that it would be difficult to
measure with confidence.
Any runtime reasons why one should be preferred over the other?

Yes, of course: There are things that can be done with a
List that cannot be done with an Iterator. If you need to sort
or shuffle the List, or peruse its contents in "random" order,
or replace an existing element with a different one, or insert
an element, or extract a sub-List, or ... All you can do with
an Iterator is visit the List's elements in whatever order the
Iterator dictates, and (perhaps) remove the most recently visited
element. Heck, given only an Iterator you can't even find the
List's size! (Lest anyone be thinking "Iterate and count," answer
me this: Given only an Iterator, how many times has its next()
method already been called?)

Decide what you're trying to do, and *then* decide how to
do it. Horse the before cart the put don't.
 
D

Donkey Hottie

Adam Lipscombe said:
Point taken. thanks.

I was think more in terms of execution speed.


thanks - adam

I have a feeling that you pondereda about the execution speed of the method
call only.

All objects passed to a method are just the reference to the object. There
will be no difference in the method all if the object is an ArrayList or an
Iterator. They are both Objects, and they have a similar reference.
 
E

Eric Sosman

Donkey said:
I have a feeling that you pondereda about the execution speed of the
method call only.

All objects passed to a method are just the reference to the object.
There will be no difference in the method all if the object is an
ArrayList or an Iterator. They are both Objects, and they have a similar
reference.

It seemed to me he was wondering about the difference of
passing a List to a method that would then create an Iterator
and traverse the List with it, versus passing a ready-made
Iterator in the first place. True, the method no longer need
do the work of creating the Iterator. But *somebody* must do
that work! If the caller does it, the work has merely been
moved from one location to another, not eliminated.

If the caller wanted to do another, independent traversal
of the same List, it is just barely within the outer limits
of possibility that it might be a skillionth of a milliquiver
faster to create an Iterator and clone() it (if it's Cloneable)
and use the copies than to create two Iterators. That's the
sort of thing I was thinking of when I wrote about differences
so small they'd be difficult to measure.

Earlier, I gave some examples of things you could do with
a List that you could not do with an Iterator. For balance,
I should point out that there are things an Iterator can do
that a List cannot, like retrieve elements of collections
other than Lists. If I want a method that "Visits all the
elements of a something-or-other," writing the method to take
an Iterator allows me to use it with Lists, Sets, BeanContexts,
or anything else that can provide an Iterator. The choice of
what to use should be driven primarily by what needs doing
(or what might someday need doing), and only secondarily by
concerns of performance. Doing wrong rapidly ain't right.
 
R

Roedy Green

Are there any advantages in speed in passing a List or an Iterator as a method parameter, or as a method return value?
Any runtime reasons why one should be preferred over the other?

The advantage of an Iterator is the client can't modify your original
list. You can also use Collections.unmodifiableList.

Iterator is more general. You could for example later modify the
producer to fetch records from a sequential file, without having to
change the client.

The general rule is avoid giving your client any more power than they
absolutely need to get the job done.

--
Roedy Green Canadian Mind Products
http://mindprod.com

"The industrial civilisation is based on the consumption of energy resources that are inherently limited in quantity, and that are about to become scarce. When they do, competition for what remains will trigger dramatic economic and geopolitical events; in the end, it may be impossible for even a single nation to sustain industrialism as we have know it in the twentieth century."
~ Richard Heinberg, The Party’s Over: Oil, War, and the Fate of Industrial Societies
 
L

Lew

Roedy said:
The advantage of an Iterator is the client can't modify your original
list.

Unless it uses
<http://java.sun.com/javase/6/docs/api/java/util/Iterator.html#remove()
Iterator is more general.  You could for example later modify the
producer to fetch records from a sequential file, without having to
change the client.

The general rule is avoid giving your client any more power than they
absolutely need to get the job done.

I guess you're focusing on returning an Iterator, as opposed to
passing one in as an argument.

In the argument scenario you need more work to avoid the concurrent
modification issues other respondents have mentioned.

Even in the return scenario, you might get more joy returning an
Iterable than an Iterator.
 
A

Arne Vajhøj

Adam said:
Point taken. thanks.

I was think more in terms of execution speed.

Spending time thinking about constant differences of different
ways of using collections are usually a big waste of time today.

Learn the big O characteristics of different collections for
different operations.

And leave the rest of the optimization to the JIT.

Arne
 
A

Arne Vajhøj

Lew said:
A ConcurrentModificationException will kill your execution speed.

Getting wrong results, or being unable to get any results, will render
speed advantages moot.

You could argue that Iterator and ConcurrentModificationException is
a lot better than unpredictable results of unsynchronized modifications
to the list.

Arne
 
L

Lew

Arne said:
You could argue that Iterator and ConcurrentModificationException is
a lot better than unpredictable results of unsynchronized modifications
to the list.

You could also argue that correct coding to avoid both
ConcurrentModificationException and unpredictable results is better still.

I don't see how stopping the process with a CME and getting no results is viable.
 
M

Mike Schilling

Lew said:
Unless it uses
<http://java.sun.com/javase/6/docs/api/java/util/Iterator.html#remove()


I guess you're focusing on returning an Iterator, as opposed to
passing one in as an argument.

In the argument scenario you need more work to avoid the concurrent
modification issues other respondents have mentioned.

Even in the return scenario, you might get more joy returning an
Iterable than an Iterator.

Like most of these questions, it depends on what you're really doing.
If you're passing something that can be iterated over more than once
(e.g. the children of a DOM Node), pass Iterable. If it can only be
iterated over once and then it's gone (e.g. a series of SAX events
generated from an InputStream), pass Iterator.

You can probably tell that I've been doing a lot of XML programming
lately.
 
M

Mike Schilling

Arne said:
You could argue that Iterator and ConcurrentModificationException is
a lot better than unpredictable results of unsynchronized
modifications to the list.

If you're returning a List to a caller, it had better be one of:

1. Unmodifiable
2. Created specifically to be returned
3. Part of a data structure owned by the calling thread
 
T

Tom Anderson

Like most of these questions, it depends on what you're really doing.
If you're passing something that can be iterated over more than once
(e.g. the children of a DOM Node), pass Iterable. If it can only be
iterated over once and then it's gone (e.g. a series of SAX events
generated from an InputStream), pass Iterator.

You can probably tell that I've been doing a lot of XML programming
lately.

Do you have a way of getting an Iterable interface in the mix here
somewhere? I had a related, although simpler, problem recently, and was
very happy to be able to work an Iterable in, because i could then
for-loop over it. If a DOM node can be iterated in several ways, it can't
be Iterable itself, but could you have its getChildren etc methods return
some sort of NodeSequence object which, while not necessarily a full-blown
List, was Iterable? Is there any reasonable way to combine this with
one-shotness?

tom
 
A

Andreas Leitgeb

Tom Anderson said:
Do you have a way of getting an Iterable interface in the mix here
somewhere? I had a related, although simpler, problem recently, and was
very happy to be able to work an Iterable in, because i could then
for-loop over it. If a DOM node can be iterated in several ways, it can't
be Iterable itself, but could you have its getChildren etc methods return
some sort of NodeSequence object which, while not necessarily a full-blown
List, was Iterable? Is there any reasonable way to combine this with
one-shotness?

In Java, the solution to this usually boils down to anonymous classes:

Iterable<Node> getChildrenIterable() {
final Iterator<Node> it= getChildrenIterator();
return new Iterable<Node>() {
public Iterator<Node> iterator() { return it; }
}
}

(untested!)
 
L

Lew

Andreas said:
In Java, the solution to this usually boils down to anonymous classes:

Iterable<Node> getChildrenIterable() {
final Iterator<Node> it= getChildrenIterator();
return new Iterable<Node>() {
public Iterator<Node> iterator() { return it; }
}
}

(untested!)

Naturally the anonymity is a tangential detail. It's trivial to give such a
class a name, just not usually necessary.
 
M

Mike Schilling

Tom said:
Do you have a way of getting an Iterable interface in the mix here
somewhere? I had a related, although simpler, problem recently, and
was very happy to be able to work an Iterable in, because i could
then
for-loop over it. If a DOM node can be iterated in several ways, it
can't be Iterable itself, but could you have its getChildren etc
methods return some sort of NodeSequence object which, while not
necessarily a full-blown List, was Iterable? Is there any reasonable
way to combine this with one-shotness?

We've got quite a bit of infrastructure built around DOMs. It
predates Iterable, but includes what amounts to an Iterator that
reutnrs only the children of an Element that are themselves Elements.
(It predates generics as well, so making it a real Iterator was less
useful than making it return Elements rather than Objects that need to
be cast.) Building something similar on top of SAX or better yet STAX
wouldn't be difficult.
 
M

Mike Schilling

Lew said:
Naturally the anonymity is a tangential detail. It's trivial to
give
such a class a name, just not usually necessary.

Speaking of which, a semi-tangential question: has anyone ever found
a use for a local class (i.e, a class defined inside a method, just
like an anonymous class, but given a name)? I never have.
 
A

Andreas Leitgeb

Mike Schilling said:
Exactly.

Speaking of which, a semi-tangential question: has anyone ever found
a use for a local class (i.e, a class defined inside a method, just
like an anonymous class, but given a name)? I never have.

I haven't yet had a use for it myself, but I could think of a few:

1) An aesthetic tradeoff: you give that class a name, and in return you
avoid having a line without the "class" keyword but followed by a
class-body.
2) with a named class you can also have your own constructor with parameters,
while still sugar'ing away the need to pass finals explicitly.
3) One may instantiate the same class at multiple places within the same
method. (e.g. for a couple of switch-cases.)
 
M

Mike Schilling

Andreas said:
I haven't yet had a use for it myself, but I could think of a few:

1) An aesthetic tradeoff: you give that class a name, and in return
you avoid having a line without the "class" keyword but followed
by
a class-body.
2) with a named class you can also have your own constructor with
parameters, while still sugar'ing away the need to pass finals
explicitly. 3) One may instantiate the same class at multiple places
within the same method. (e.g. for a couple of switch-cases.)

All good points. Of course, when any of them apply, you've also got
to consider "Might I want to use this class in another method? If so,
I might as well make it a full-fledged nested class." Anyway, had
local classes never been invented, I doubt we'd miss them.
 
L

Lew

Mike said:
All good points. Of course, when any of them apply, you've also got
to consider "Might I want to use this class in another method? If so,
I might as well make it a full-fledged nested class." Anyway, had
local classes never been invented, I doubt we'd miss them.

There was a reason why they were added to the Java language. Obviously
somebody missed them.

They fill the gap for which other languages use delegates or closures, among
other things.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top