List or Iterator

Discussion in 'Java' started by Adam Lipscombe, Jul 24, 2009.

  1. 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
    Adam Lipscombe, Jul 24, 2009
    #1
    1. Advertising

  2. Adam Lipscombe

    Lew Guest

    Adam Lipscombe wrote:
    > 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.

    --
    Lew
    Lew, Jul 24, 2009
    #2
    1. Advertising

  3. Adam Lipscombe

    Eric Sosman Guest

    Adam Lipscombe wrote:
    > 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.

    --
    Eric Sosman
    lid
    Eric Sosman, Jul 24, 2009
    #3
  4. "Adam Lipscombe" <> wrote in
    message news:
    >
    > 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.
    Donkey Hottie, Jul 24, 2009
    #4
  5. Adam Lipscombe

    Eric Sosman Guest

    Donkey Hottie wrote:
    > "Adam Lipscombe" <> wrote in
    > message news:
    >>
    >> 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.


    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.

    --
    Eric Sosman
    lid
    Eric Sosman, Jul 24, 2009
    #5
  6. Adam Lipscombe

    Roedy Green Guest

    On Fri, 24 Jul 2009 14:20:44 +0100, Adam Lipscombe
    <> wrote, quoted or indirectly quoted someone
    who said :

    >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
    Roedy Green, Jul 24, 2009
    #6
  7. Adam Lipscombe

    Lew Guest

    Roedy Green wrote:
    > 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.

    --
    Lew
    Lew, Jul 24, 2009
    #7
  8. Adam Lipscombe

    Arne Vajhøj Guest

    Adam Lipscombe wrote:
    > Eric Sosman wrote:
    >> Adam Lipscombe wrote:
    >>> 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.

    >
    > 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
    Arne Vajhøj, Jul 25, 2009
    #8
  9. Lew wrote:
    > Adam Lipscombe wrote:
    >> Point taken. thanks.
    >>
    >> I was think more in terms of execution speed.

    >
    > 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
    Arne Vajhøj, Jul 25, 2009
    #9
  10. Adam Lipscombe

    Lew Guest

    Arne Vajhøj wrote:
    > Lew wrote:
    >> Adam Lipscombe wrote:
    >>> Point taken. thanks.
    >>>
    >>> I was think more in terms of execution speed.

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


    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.

    --
    Lew
    Lew, Jul 25, 2009
    #10
  11. Lew wrote:
    > Roedy Green wrote:
    >> 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.


    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.
    Mike Schilling, Jul 25, 2009
    #11
  12. Arne Vajhøj wrote:
    > Lew wrote:
    >> Adam Lipscombe wrote:
    >>> Point taken. thanks.
    >>>
    >>> I was think more in terms of execution speed.

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


    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
    Mike Schilling, Jul 25, 2009
    #12
  13. Adam Lipscombe

    Tom Anderson Guest

    On Sat, 25 Jul 2009, Mike Schilling wrote:

    > Lew wrote:
    >> Roedy Green wrote:
    >>> 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.

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

    --
    She got destiny, she got supremacy, she got everything ever from A to Z.
    Tom Anderson, Jul 26, 2009
    #13
  14. Tom Anderson <> wrote:
    > 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!)
    Andreas Leitgeb, Jul 26, 2009
    #14
  15. Adam Lipscombe

    Lew Guest

    Andreas Leitgeb wrote:
    > 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.

    --
    Lew
    Lew, Jul 26, 2009
    #15
  16. Tom Anderson wrote:
    > On Sat, 25 Jul 2009, Mike Schilling wrote:
    >
    >> Lew wrote:
    >>> Roedy Green wrote:
    >>>> 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.

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


    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.
    Mike Schilling, Jul 26, 2009
    #16
  17. Lew wrote:
    > Andreas Leitgeb wrote:
    >> 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.


    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.
    Mike Schilling, Jul 26, 2009
    #17
  18. Mike Schilling <> wrote:
    > Lew wrote:
    >> Andreas Leitgeb wrote:
    >>> 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.

    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.)
    Andreas Leitgeb, Jul 27, 2009
    #18
  19. Andreas Leitgeb wrote:
    > Mike Schilling <> wrote:
    >> Lew wrote:
    >>> Andreas Leitgeb wrote:
    >>>> 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.

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


    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.
    Mike Schilling, Jul 27, 2009
    #19
  20. Adam Lipscombe

    Lew Guest

    Mike Schilling wrote:
    > 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.

    --
    Lew
    Lew, Jul 27, 2009
    #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. Hendrik Maryns
    Replies:
    18
    Views:
    1,421
  2. greg
    Replies:
    6
    Views:
    456
    Dietmar Kuehl
    Jul 17, 2003
  3. Replies:
    6
    Views:
    643
    Jim Langston
    Oct 30, 2005
  4. Steven D'Aprano

    What makes an iterator an iterator?

    Steven D'Aprano, Apr 18, 2007, in forum: Python
    Replies:
    28
    Views:
    1,156
    Steven D'Aprano
    Apr 20, 2007
  5. David Bilsby
    Replies:
    5
    Views:
    2,044
    David Bilsby
    Oct 9, 2007
Loading...

Share This Page