Wayne said:
I don't understand the question. What goes in the for loop
in place of the "..."? Surely some call to "ArrayList.get()"?
In the Iterator case, an Iterator.next() goes in the loop, and normally
some use of the object thereby retrieved. This is to be compared to the
indexed loop in which case, as you say, an ArrayList.get(i) goes in the
loop, along with the same use of the retrieved object.
So the resulting byte code should be nearly identical and
dominated by the method calls, right?
If you look at the byte codes in detail then there are plenty of
differences, but the general schemes are about the same. Each one
contains two method invocations per loop iteration. (Disregarding the
part of the loop that does the real work.) The time might be dominated
by the method invocations, but more bytecodes are devoted to
manipulating variables and operands.
Multi-Threading issues aside, when will this be faster?
Do you mean the previous or the following? As I wrote before,
timing-wise and for ArrayLists specifically, the two above approaches
are pretty much equivalent. The Iterator approach provides better
encapsulation when the specific indices are not significant. The
Iterator approach performs _much_ better than the indexed approach for
some other kinds of Lists (e.g. LinkedLists), and so using that approach
also insulates your code from changes to the List implementation used.
Object [] array = list.toArray();
for ( int i = 0; i < array.length; ++i )
{
...array...
}
It seems that is should be a lot faster since the method calls
in the loop body have been replaced with a single method call
outside. Or is that what the original question was about?
That is not what the original question was about, but it does bear some
discussion. It might sometimes be useful to do exactly as you describe,
but doing so is unlikely to be faster. That's because in order to
construct the array it is necessary to perform a sequence of operations
equivalent to the code we were talking about before. Only after that is
complete is the real work done in your example. Moreover, constructing
an intermediate array consumes more memory; this is not of much concern
if the operation is not performed too often and the original List is not
too large, but otherwise it could be a problem.
It could be useful to construct that intermediate array when you want to
enforce stricter typing in the loop body without using casts there.
Instead of the first line of your example you would use
MyType[] array = (MyType[]) list.toArray(new MyType[0]);
or something similar. Actually, now that I look at it, I'm not sure
that that gives much advantage at all. Perhaps you'll see some.
John Bollinger
(e-mail address removed)