looping through a list, starting at 1

S

Stefan Ram

Assuming a list has a sufficient number of entries at run
time, what should be prefered to assign a reference to each
entry to »e«, starting at index 1:

for( final E e : l.sublist( 1, l.size() ))...

or

for( int i = 1; i < l.size(); ++i ){ final E e = l.get( 0 ); ... }

?
 
A

Andreas Leitgeb

Stefan Ram said:
Assuming a list has a sufficient number of entries at run
time, what should be prefered to assign a reference to each
entry to »e«, starting at index 1:
for( final E e : l.sublist( 1, l.size() ))...
This appears to be the most elegant and general approach.
for( int i = 1; i < l.size(); ++i ){ final E e = l.get( 0 ); ... }
for an ArrayList-like implementation, this one may perform well,
while for a LinkedList-alike it will scale rather bad for large lists.

Another option would be to get an iterator from your list, pre-advance
it once, then use a while-loop on it.hasNext() ...
Iterator<E> it = l.iterator();
it.next(); // skip first (assuming a list has ...)
while (it.hasNext()) {
final E e = it.next();
...
}
 
A

Arved Sandstrom

This is the sort of situation in which I try writing a comment, even if
I don't leave it in the code. The form that makes the comment easier to
write is the one that better models programmer intent.

Patricia

It's a good idea. As it happens I think you'd end up with a comment no
matter what, simply to explain why you're skipping the first element.

I prefer the sublist-based foreach loop out of the 3 options presented
by Stefan and Andreas: both it and the standard 'for' loop highlight the
start index as a number, but the foreach more clearly emphasizes the
range being operated on. IMO.

AHS
 
A

Arne Vajhøj

Assuming a list has a sufficient number of entries at run
time, what should be prefered to assign a reference to each
entry to »e«, starting at index 1:

for( final E e : l.sublist( 1, l.size() ))...

or

for( int i = 1; i< l.size(); ++i ){ final E e = l.get( 0 ); ... }

?

You mean l.get(i) I assume!?

If l is List<> then you will have to go for the first.

If l is ArrayList<> then I would for for the second - it is
a more clear approach.

Arne
 
E

Eric Sosman

Assuming a list has a sufficient number of entries at run
time, what should be prefered to assign a reference to each
entry to »e«, starting at index 1:

for( final E e : l.sublist( 1, l.size() ))...

or

for( int i = 1; i< l.size(); ++i ){ final E e = l.get( 0 ); ... }

(ITYM l.get(i)?)

How about

Iterator<E> it = l.iterator();
it.next(); // ignore element 0
while (it.hasNext()) {
E e = it.next();
...
}

In short, there may well be half-a-dozen ways to do what you ask,
if not more. None of them stands out as "preferred" to my eye;
you may as well do whatever seems natural.

... and "natural" is a little unnatural, it seems to me. If
the various E are truly independent -- if l is merely a Collection
for the purposes of the loop -- one wonders where the interloper at
position 0 came from. And if the position really matters -- maybe
you're looking at adjacent pairs or something -- then clearly i has
more significance than a purely synthetic iteration control would
(hence your second form would be preferred, because somewhere in the
body you'd be doing l.get(i-1).) As a problem in the abstract I see
no clear reason to choose one form over its peers; with a concrete
context I might.
 
S

Stefan Ram

Eric Sosman said:
... and "natural" is a little unnatural, it seems to me. If
the various E are truly independent -- if l is merely a Collection
for the purposes of the loop -- one wonders where the interloper at
position 0 came from.

This is code for my new mark-up language. A section might
look like:

< [This is an example heading]

[This is the first paragraph of the body.]

[This is the last paragraph of the body.] >

. The first entry of a section always is interpreted as its
heading, so a heading does not require additional mark-up.

The code to convert this section to HTML converts the first
entry »[This is an example heading]« into an HTML heading
element. Then it loops through the rest of the entries to
convert them to HTML paragraph elements.
 
R

Robert Klemme

You mean l.get(i) I assume!?

If l is List<> then you will have to go for the first.

You should at least mention that this is mostly for performance
reasons. Method get(int) is present in List interface and can be used
on any list:
http://download.oracle.com/javase/6/docs/api/java/util/List.html#get(int)
If l is ArrayList<> then I would for for the second - it is
a more clear approach.

I'd go with the sublist approach - it's the more declarative way to do
it plus it is asymptotically more efficient if the list is some form
of linked list.

If there are performance issues then we can optimize later anyway.

Kind regards

robert
 
E

Eric Sosman

Eric Sosman said:
... and "natural" is a little unnatural, it seems to me. If
the various E are truly independent -- if l is merely a Collection
for the purposes of the loop -- one wonders where the interloper at
position 0 came from.

This is code for my new mark-up language. A section might
look like:

< [This is an example heading]

[This is the first paragraph of the body.]

[This is the last paragraph of the body.]>

. The first entry of a section always is interpreted as its
heading, so a heading does not require additional mark-up.

The code to convert this section to HTML converts the first
entry »[This is an example heading]« into an HTML heading
element. Then it loops through the rest of the entries to
convert them to HTML paragraph elements.

It seems to me that the heading doesn't belong in the same
List as the remaining entries: It has special significance and
gets special handling. "I'm at position zero, so..." doesn't
stand out as a robust signifier of the heading's specialness,
and you might want to consider whether to manifest it in other
ways. For example, suppose you decide to introduce the notion
of sub-headings: You'll now need three treatments, but "I'm at
zero" can only divide one of them from the other two. Or maybe
you'd like to generate an index of all the section headings: In
a List of nothing but headings, "I'm at zero" is not special.

One possibility would be to keep the List, but to delegate
the formatting style to the entry itself. Make E abstract with
an abstract toHTML() method, and let headings and body entries
subclass it to provide their own implementations. Implementing
sub-headings then just amounts to writing a new E subclass. For
flexibility's sake, maybe E shouldn't just be "entry" but "entry
with formatter" so you can easily inject other formatters for
generating indexes, tables of contents, "site maps," and so on.

But there ought to be something more significant than "I'm
at position zero" to trigger the special handling. Just sayin'.
 
S

Stefan Ram

Eric Sosman said:
It seems to me that the heading doesn't belong in the same
List as the remaining entries: It has special significance and
gets special handling. "I'm at position zero, so..." doesn't
stand out as a robust signifier of the heading's specialness,

The previous version of that mark-up language indeed had this:

< &text heading = [This is an example heading]
[This is the first paragraph of the body.]
[This is the last paragraph of the body.] >

But I wanted to reduced notational clutter.
(The »&text« element type was not shown in my previous
post in order to simplify things a bit.)
and you might want to consider whether to manifest it in other
ways. For example, suppose you decide to introduce the notion
of sub-headings: You'll now need three treatments, but "I'm at
zero" can only divide one of them from the other two. Or maybe
you'd like to generate an index of all the section headings: In
a List of nothing but headings, "I'm at zero" is not special.

A subheading could be written as follows

< &text < &text [This is the main heading]
[This is the sub heading] >
[This is the first paragraph of the body.]
[This is the last paragraph of the body.] >

Above, the heading of the outer text (the first two lines)
is structured as a text itself.
But there ought to be something more significant than "I'm
at position zero" to trigger the special handling. Just sayin'.

The new text notation is based on the observation that a
text often expresses a binary relation between two subtexts.
A heading and its body is just one example. Another example
would be the relation between a word and its translation in
a bilingual dictionary. Since this appears so often, I decided
to make the interpretation of the first entry as one part
of this binary relation the default.

A list of dictionary entries in the old mark-up style would
look like:

< &text heading = [English-Italian dictionary]
< &translation from=[As I understand it] to=[Per come ho capito] >
< &translation from=[Also known as] to=[Conosciuto anche come] >>

The new mark-up style omits »heading«, »from« and »to«:

< &text [English-Italian dictionary]
< &translation [As I understand it] [Per come ho capito] >
< &translation [Also known as] [Conosciuto anche come] >>

A possible future extension could use »list« to write the
type of all subelements once in an element without the need
to repeat it for every subelement:

< &text list=translation
[English-Italian dictionary]
< [As I understand it] [Per come ho capito] >
< [Also known as] [Conosciuto anche come] >>

Now, in the first line, the type »text« implies that the
first entry (appearing in the second line) is a heading and
»list=translation« that the pairs are translations, while
the rest of the lines has very little notational clutter,
so it is easier to read and edit even in the source code.
 
V

Volker Borchert

Robert said:
If there are performance issues then we can optimize later anyway.

In that case, I'd go for something like

if (l instanceof RandomAccess) {
for (int i = 1, n = l.size(); i < n; ++i) {
final E e = l.get(i);
// ...
}
} else {
final Iterator i = l.iterator();
if (i.hasNext()) {
i.next();
while (i.hasNext()) {
final E e = i.next();
// ...
}
}
}

and hope that all custom List implementations encountered truthfully
implement or not RandomAccess, and that those that do have a fast size()
and those that don't have a fast Iterator.hasNext().
 
C

Chris Riesbeck

(ITYM l.get(i)?)

How about

Iterator<E> it = l.iterator();
it.next(); // ignore element 0
while (it.hasNext()) {
E e = it.next();
...
}

In short, there may well be half-a-dozen ways to do what you ask,
if not more. None of them stands out as "preferred" to my eye;
you may as well do whatever seems natural.

To add yet another option, if you are writing lots of iterations over
the "tail" of a collection, then you could define an Iterable wrapping
class, like this:

public class Tail<T> implements Iterable<T> {

public static <T> Tail<T> tail(final Iterable<T> coll) {
return new Tail<T>(coll);
}

public Iterator<T> iterator() {
return iter;
}

private Iterator<T> iter;

private Tail(final Iterable<T> coll) {
iter = coll.iterator();
if (iter.hasNext()) iter.next();
}
}

then to use

import static utils.Tail.tail;

...

for (final E e : tail( list )) {
...
}
 
M

markspace

import static utils.Tail.tail;

for (final E e : tail( list )) {
...
}


I like the static factory idea, but why define a whole new class?

public class CollectionUtils {

public static <T> List<T> skip( int n, List<T> list ) {
return list.sublist( n, list.size() ) ;
}

public static <T> List<T> skip( List<T> list ) {
return skip( 1, list ) ;
}

....
 
C

Chris Riesbeck

I like the static factory idea, but why define a whole new class?

public class CollectionUtils {

public static <T> List<T> skip( int n, List<T> list ) {
return list.sublist( n, list.size() ) ;
}

public static <T> List<T> skip( List<T> list ) {
return skip( 1, list ) ;
}

Just generality ... Tail.tail() only requires something that's Iterable,
not a List.
 
R

Roedy Green

for( int i = 1; i < l.size(); ++i ){ final E e = l.get( 0 ); ... }

This one is clearer. The problem is most people will just glance at it
and read it as for( int i=0; i<l.zise(); i++ )

I think you mean i++ not ++i.


you might use for ( E e : l )
Then use logic to avoid the first elt, though that is overkill for
ensuring noone misreads your code.
 
A

Arved Sandstrom

This one is clearer. The problem is most people will just glance at it
and read it as for( int i=0; i<l.zise(); i++ )

Errr, I don't know if "most" people would misread the above, although no
doubt some would, but how can you assert that something is more clear
then immediately assert that most people will mis-read it?
I think you mean i++ not ++i.

In this particular case why would it matter? Write a simple test case
that has 2 loops, one using pre-increment for the increment expression,
one using post-increment, and see if there's a difference. There won't
be: the increment expression is invoked *after* each iteration through
the loop.
you might use for ( E e : l )
Then use logic to avoid the first elt, though that is overkill for
ensuring noone misreads your code.

AHS
 
E

Eric Sosman

This one is clearer. The problem is most people will just glance at it
and read it as for( int i=0; i<l.zise(); i++ )

Soundz! Can beingz unable to diztinguizh onez from seroez exizt
outzide of sooz?
I think you mean i++ not ++i.

Say what? Or, rather, say why?
 
G

Gene Wirchenko

Soundz! Can beingz unable to diztinguizh onez from seroez exizt
outzide of sooz?

Mr. Zozman, pleaze do not make fun of Roedy.
Say what? Or, rather, say why?

Add me to the list of those asking why.

Sincerely,

Gene Wirchenko
 
R

RedGrittyBrick

IIUC, the result of evaluating any ForUpdate expression is discarded,
so I'm not sure how the difference would matter.

Since I see postincrement a lot more than I see preincrement and since
i++ is idiomatic in that construct, when seeing ++i I tend to stop and
wonder whether the writer intended something else. So I suppose it might
matter if engendering a sense of distrust or unease in maintenance
programmers matters.
 

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,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top