looping through a list, starting at 1

Discussion in 'Java' started by Stefan Ram, Aug 1, 2011.

  1. Stefan Ram

    Stefan Ram Guest

    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 ); ... }

    ?
     
    Stefan Ram, Aug 1, 2011
    #1
    1. Advertising

  2. Stefan Ram <-berlin.de> wrote:
    > 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();
    ...
    }
     
    Andreas Leitgeb, Aug 2, 2011
    #2
    1. Advertising

  3. On 11-08-01 08:13 PM, Patricia Shanahan wrote:
    > On 8/1/2011 3:45 PM, Stefan Ram wrote:
    >> 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 ); ... }
    >>
    >> ?
    >>

    >
    > 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
     
    Arved Sandstrom, Aug 2, 2011
    #3
  4. Stefan Ram

    Arne Vajhøj Guest

    On 8/1/2011 6:45 PM, Stefan Ram wrote:
    > 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
     
    Arne Vajhøj, Aug 2, 2011
    #4
  5. Stefan Ram

    Stefan Ram Guest

    Arne Vajhøj <> writes:
    >>for( int i = 1; i< l.size(); ++i ){ final E e = l.get( 0 ); ... }

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


    Yes.
     
    Stefan Ram, Aug 2, 2011
    #5
  6. Stefan Ram

    Eric Sosman Guest

    On 8/1/2011 6:45 PM, Stefan Ram wrote:
    > 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.

    --
    Eric Sosman
    d
     
    Eric Sosman, Aug 2, 2011
    #6
  7. Stefan Ram

    Stefan Ram Guest

    Eric Sosman <> writes:
    > ... 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.
     
    Stefan Ram, Aug 2, 2011
    #7
  8. On 2 Aug., 02:32, Arne Vajhøj <> wrote:
    > On 8/1/2011 6:45 PM, Stefan Ram wrote:
    >
    > >    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.


    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
     
    Robert Klemme, Aug 2, 2011
    #8
  9. Stefan Ram

    Eric Sosman Guest

    On 8/1/2011 10:43 PM, Stefan Ram wrote:
    > Eric Sosman<> writes:
    >> ... 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'.

    --
    Eric Sosman
    d
     
    Eric Sosman, Aug 2, 2011
    #9
  10. Stefan Ram

    Stefan Ram Guest

    Eric Sosman <> writes:
    > 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.
     
    Stefan Ram, Aug 2, 2011
    #10
  11. Robert Klemme wrote:
    > 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().

    --

    "I'm a doctor, not a mechanic." Dr Leonard McCoy <>
    "I'm a mechanic, not a doctor." Volker Borchert <>
     
    Volker Borchert, Aug 2, 2011
    #11
  12. On 8/1/2011 8:50 PM, Eric Sosman wrote:
    > On 8/1/2011 6:45 PM, Stefan Ram wrote:
    >> 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.


    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 )) {
    ...
    }
     
    Chris Riesbeck, Aug 2, 2011
    #12
  13. Stefan Ram

    markspace Guest

    On 8/2/2011 12:38 PM, Chris Riesbeck wrote:

    > 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 ) ;
    }

    ....
     
    markspace, Aug 2, 2011
    #13
  14. On 8/2/2011 2:50 PM, markspace wrote:
    > On 8/2/2011 12:38 PM, Chris Riesbeck wrote:
    >
    >> 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 ) ;
    > }


    Just generality ... Tail.tail() only requires something that's Iterable,
    not a List.
     
    Chris Riesbeck, Aug 3, 2011
    #14
  15. Stefan Ram

    Roedy Green Guest

    On 1 Aug 2011 22:45:41 GMT, -berlin.de (Stefan Ram) wrote,
    quoted or indirectly quoted someone who said :

    >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.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Most of computer code is for telling the computer
    what do if some very particular thing goes wrong.
     
    Roedy Green, Aug 3, 2011
    #15
  16. On 11-08-03 07:40 PM, Roedy Green wrote:
    > On 1 Aug 2011 22:45:41 GMT, -berlin.de (Stefan Ram) wrote,
    > quoted or indirectly quoted someone who said :
    >
    >> 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++ )


    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
     
    Arved Sandstrom, Aug 4, 2011
    #16
  17. Stefan Ram

    Eric Sosman Guest

    On 8/3/2011 6:40 PM, Roedy Green wrote:
    > On 1 Aug 2011 22:45:41 GMT, -berlin.de (Stefan Ram) wrote,
    > quoted or indirectly quoted someone who said :
    >
    >> 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++ )


    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?

    --
    Eric Sosman
    d
     
    Eric Sosman, Aug 4, 2011
    #17
  18. In article <>,
    Roedy Green <> wrote:

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



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

    <http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.14.1.2>

    --
    John B. Matthews
    trashgod at gmail dot com
    <http://sites.google.com/site/drjohnbmatthews>
     
    John B. Matthews, Aug 4, 2011
    #18
  19. On Wed, 03 Aug 2011 21:10:46 -0400, Eric Sosman
    <> wrote:

    >On 8/3/2011 6:40 PM, Roedy Green wrote:
    >> On 1 Aug 2011 22:45:41 GMT, -berlin.de (Stefan Ram) wrote,
    >> quoted or indirectly quoted someone who said :
    >>
    >>> 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++ )

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


    Mr. Zozman, pleaze do not make fun of Roedy.

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

    >
    > Say what? Or, rather, say why?


    Add me to the list of those asking why.

    Sincerely,

    Gene Wirchenko
     
    Gene Wirchenko, Aug 4, 2011
    #19
  20. On 04/08/2011 04:36, John B. Matthews wrote:
    > In article<>,
    > Roedy Green<> wrote:
    >
    >> I think you mean i++ not ++i.

    >
    >
    > 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.

    --
    RGB
     
    RedGrittyBrick, Aug 4, 2011
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. saoirse_79

    looping through a list of lists.

    saoirse_79, Oct 8, 2003, in forum: Python
    Replies:
    0
    Views:
    261
    saoirse_79
    Oct 8, 2003
  2. Andy
    Replies:
    3
    Views:
    501
    James Kanze
    Jun 8, 2007
  3. John Smith
    Replies:
    2
    Views:
    111
    Robert Klemme
    Oct 7, 2010
  4. Aaron
    Replies:
    2
    Views:
    579
    dhtml
    Apr 10, 2011
  5. Replies:
    5
    Views:
    307
Loading...

Share This Page