Generics and for each

Discussion in 'Java' started by Tom McGlynn, Nov 7, 2008.

  1. Tom McGlynn

    Tom McGlynn Guest

    Recently I've been trying to implement Iterable in some of my classes
    to take advantage of the for-each syntax, e.g., to loop over the
    results in a query. It doesn't work quite as nicely as I would like
    due -- I think -- to non-reifiability of generics. Here's an example
    that illustrates
    the problem.

    import java.util.ArrayList;
    import java.util.Iterator;

    public class Zz implements Iterable {

    ArrayList<String> arr = new ArrayList<String>();
    Zz() {
    arr.add("a");
    arr.add("b");
    arr.add("c");
    }

    public Iterator<String> iterator() {
    return arr.iterator();
    }
    public static void main(String[] args) {

    Zz z = new Zz();

    for (String x: z) {
    System.out.println(x);
    }
    }
    }

    This fails with an incompatible types message when compiling the for
    loop.

    If I replace 'String x' with 'Object x' all is copacetic, but as it
    stands it fails because it doesn't know that the Iterator is a
    <String> iterator. I gather that's information lost due to type
    erasure.

    Am I misunderstanding the idiom I need to do this, or do I still need
    to do the kinds of casts
    that generics were supposed to help me get rid of. I.e., is there any
    operational advantage of specifying
    public Iterator<X> iterator()
    versus
    public Iterator iterator()
    when X is a real class not a generic type. [Presumably it's still a
    good thing to do for documentation.]

    I've no doubt this has come up before -- if you can point to some
    earlier discussion or documentation I'd appreciate it.

    Regards,
    Tom McGlynn
    Tom McGlynn, Nov 7, 2008
    #1
    1. Advertising

  2. Tom McGlynn wrote:
    > Recently I've been trying to implement Iterable in some of my classes
    > to take advantage of the for-each syntax, e.g., to loop over the
    > results in a query. It doesn't work quite as nicely as I would like
    > due -- I think -- to non-reifiability of generics. Here's an example
    > that illustrates
    > the problem.
    >
    > public class Zz implements Iterable {


    Here's your problem. Iterable is a generic class: you want Iterable<String>.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Nov 7, 2008
    #2
    1. Advertising

  3. Tom McGlynn

    Tom McGlynn Guest

    On Nov 7, 1:18 pm, Joshua Cranmer <> wrote:
    > Tom McGlynn wrote:
    > > Recently I've been trying to implement Iterable in some of my classes
    > > to take advantage of the for-each syntax, e.g., to loop over the
    > > results in a query. It doesn't work quite as nicely as I would like
    > > due -- I think -- to non-reifiability of generics. Here's an example
    > > that illustrates
    > > the problem.

    >
    > > public class Zz implements Iterable {

    >
    > Here's your problem. Iterable is a generic class: you want Iterable<String>.
    >
    > --
    > Beware of bugs in the above code; I have only proved it correct, not
    > tried it. -- Donald E. Knuth



    Thanks...
    I should have realized that such a simple case had to work,
    Regards,
    Tom McGlynn, Nov 7, 2008
    #3
  4. Tom McGlynn

    Tom McGlynn Guest

    On Nov 7, 1:18 pm, Joshua Cranmer <> wrote:
    > Tom McGlynn wrote:
    > > Recently I've been trying to implement Iterable in some of my classes
    > > to take advantage of the for-each syntax, e.g., to loop over the
    > > results in a query. It doesn't work quite as nicely as I would like
    > > due -- I think -- to non-reifiability of generics. Here's an example
    > > that illustrates
    > > the problem.

    >
    > > public class Zz implements Iterable {

    >
    > Here's your problem. Iterable is a generic class: you want Iterable<String>.
    >
    > --
    > Beware of bugs in the above code; I have only proved it correct, not
    > tried it. -- Donald E. Knuth


    Thanks... I should have realized that such a simple case had to work
    and I'd made an error somewhere.
    Tom
    Tom McGlynn, Nov 7, 2008
    #4
  5. Tom McGlynn

    Lew Guest

    Tom McGlynn wrote:
    > Recently I've been trying to implement Iterable in some of my classes
    > to take advantage of the for-each syntax, e.g., to loop over the
    > results in a query.  It doesn't work quite as nicely as I would like
    > due -- I think -- to non-reifiability of generics.  



    That's not the reason. The issue occurs at compile time, therefore it
    cannot be related to reifiability, which is a run-time issue.

    You left out the type parameter on the 'implements Iterable' clause,
    so the compiler has no way of matching the 'String' type of the loop
    variable to the underlying type of the 'Iterable'.

    Add a generic type parameter as indicated below. I used 'String' to
    match your example, but it'd be better as '<T>'.

    > import java.util.ArrayList;
    > import java.util.Iterator;
    >
    > public class Zz implements Iterable


    <String> // got to nail down what *type* of Iterable it is

    > {
    >     ArrayList<String> arr = new ArrayList<String>();


    // consider using: List <String> arr = new ArrayList <String> ();

    >     Zz() {
    >         arr.add("a");
    >         arr.add("b");
    >         arr.add("c");
    >     }
    >
    >     public Iterator <String> iterator() {


    // Because you didn't implement 'Iterator <String>'
    // the compiler cannot resolve your type in the 'main()' for-each
    loop.

    >         return arr.iterator();
    >     }
    >     public static void main(String[] args) {
    >
    >         Zz z = new Zz();
    >
    >         for (String x : z) {
    >             System.out.println(x);
    >         }
    >     }
    >
    > }
    >
    > This fails with an incompatible types message when compiling the for
    > loop.


    Always but always cite the actual error message, character for
    character, preferably by copy-and-paste, rather than paraphrasing.

    > If I replace 'String x' with 'Object x' all is copacetic, but as it
    > stands it fails because it doesn't know that the Iterator is a
    > <String> iterator.  I gather that's information lost due to type
    > erasure.


    Nope. It's a compile-time issue, as you stated. Type erasure is a
    run-time phenomenon, and you would not have discovered it via a
    compile-time message.

    > Am I misunderstanding the idiom I need to do this,


    Yes.

    > or do I still need to do the kinds of casts


    Nope.

    > that generics were supposed to help me get rid of.  I.e., is there any
    > operational advantage of specifying
    >     public Iterator<X> iterator()
    > versus
    >     public Iterator iterator()
    > when X is a real class not a generic type.


    Not if you neglect the type parameter in the 'implements' clause,
    there isn't.

    Even better than '<String>':

    <sscce>
    package eegee;

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    /** Zz illustrates how to implement <code>Iterable</code>.
    * @param <T> generic type of iterator.
    */
    public class Zz <T> implements Iterable <T>
    {
    List <T> arr = new ArrayList <T> ();

    @Override
    public Iterator <T> iterator()
    {
    return arr.iterator();
    }

    /** Add an element.
    * @param val <code>T</code> element to add.
    * @return boolean <code>true</code> iff the add succeeds.
    */
    public boolean add( T val )
    {
    return arr.add( val );
    }

    /** Main method.
    * @param args <code>String []</code> arguments.
    */
    public static void main( String [] args )
    {
    Zz <String> z = new Zz <String> ();

    z.add( "a" );
    z.add( "b" );
    z.add( "c" );

    for ( String x : z )
    {
    System.out.println(x);
    }
    }
    }
    </sscce>

    run:
    a
    b
    c
    BUILD SUCCESSFUL (total time: 1 second)

    --
    Lew
    Lew, Nov 7, 2008
    #5
  6. Tom McGlynn

    Tom McGlynn Guest

    Thanks again to you and Joshua. Should know better than to post after
    only a couple of hours sleep!

    I suspect I would have looked at it for a long long time without
    realizing what I was doing wrong.
    Regards,
    Tom McGlynn
    Tom McGlynn, Nov 7, 2008
    #6
  7. Tom McGlynn

    Roedy Green Guest

    On Fri, 7 Nov 2008 09:42:59 -0800 (PST), Tom McGlynn
    <> wrote, quoted or indirectly quoted
    someone who said :

    >public class Zz implements Iterable {


    You meant:

    public class Zz implements Iterable<String> {

    Lots of redundancy required with generics.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Your old road is
    Rapidly agin'.
    Please get out of the new one
    If you can't lend your hand
    For the times they are a-changin'.
    Roedy Green, Nov 8, 2008
    #7
  8. Tom McGlynn

    Roedy Green Guest

    On Fri, 7 Nov 2008 09:42:59 -0800 (PST), Tom McGlynn
    <> wrote, quoted or indirectly quoted
    someone who said :

    >
    >public class Zz implements Iterable {


    see http://mindprod.com/jgloss/iterator.html#ITERABLE
    for sample code.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Your old road is
    Rapidly agin'.
    Please get out of the new one
    If you can't lend your hand
    For the times they are a-changin'.
    Roedy Green, Nov 8, 2008
    #8
  9. Tom McGlynn wrote:
    > Thanks again to you and Joshua. Should know better than to post
    > after
    > only a couple of hours sleep!
    >
    > I suspect I would have looked at it for a long long time without
    > realizing what I was doing wrong.


    Sometimes, especially when you know that the problem is something
    simple but you can't find it, the key is to *stop* looking at it for a
    while. Take a nap, go for a walk, read a book, or whatever you think
    will clear your mind, and then come back and look at it with fresh
    eyes. I couldn't begin to tell you how many times after I've spent
    all day fighting with something I've figured it out on the drive home.
    Mike Schilling, Nov 8, 2008
    #9
  10. Mike Schilling wrote:
    > Tom McGlynn wrote:
    >> Thanks again to you and Joshua. Should know better than to post
    >> after
    >> only a couple of hours sleep!
    >>
    >> I suspect I would have looked at it for a long long time without
    >> realizing what I was doing wrong.

    >
    > Sometimes, especially when you know that the problem is something
    > simple but you can't find it, the key is to *stop* looking at it for a
    > while. Take a nap, go for a walk, read a book, or whatever you think
    > will clear your mind, and then come back and look at it with fresh
    > eyes. I couldn't begin to tell you how many times after I've spent
    > all day fighting with something I've figured it out on the drive home.


    I have at least two separate instances where I've been stuck on a
    problem and gave up. As I was thinking to myself later in the shower,
    the answer revealed itself with a clear, perfect resolution. Makes me
    feel like Archimedes.

    Disclaimers: Both the problems were programming problems, not problems
    of determining density. Also, I did not run through the house or city
    naked. I had a bathrobe on.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Nov 8, 2008
    #10
  11. Joshua Cranmer wrote:
    > Mike Schilling wrote:
    >> Tom McGlynn wrote:
    >>> Thanks again to you and Joshua. Should know better than to post after
    >>> only a couple of hours sleep!
    >>>
    >>> I suspect I would have looked at it for a long long time without
    >>> realizing what I was doing wrong.

    >>
    >> Sometimes, especially when you know that the problem is something
    >> simple but you can't find it, the key is to *stop* looking at it for a
    >> while. Take a nap, go for a walk, read a book, or whatever you think
    >> will clear your mind, and then come back and look at it with fresh
    >> eyes. I couldn't begin to tell you how many times after I've spent
    >> all day fighting with something I've figured it out on the drive home.

    >
    > I have at least two separate instances where I've been stuck on a
    > problem and gave up. As I was thinking to myself later in the shower,
    > the answer revealed itself with a clear, perfect resolution. Makes me
    > feel like Archimedes.
    >
    > Disclaimers: Both the problems were programming problems, not problems
    > of determining density. Also, I did not run through the house or city
    > naked. I had a bathrobe on.
    >


    I sometimes take this a stage further - go to sleep stuck, but wake up
    knowing the solution. I sometimes wonder how I would manage if I were
    paid per hour. Obviously, part of my brain was working on the problem
    overnight...

    Patricia
    Patricia Shanahan, Nov 8, 2008
    #11
  12. Tom McGlynn

    Arne Vajhøj Guest

    Mike Schilling wrote:
    > Tom McGlynn wrote:
    >> Thanks again to you and Joshua. Should know better than to post
    >> after
    >> only a couple of hours sleep!
    >>
    >> I suspect I would have looked at it for a long long time without
    >> realizing what I was doing wrong.

    >
    > Sometimes, especially when you know that the problem is something
    > simple but you can't find it, the key is to *stop* looking at it for a
    > while. Take a nap, go for a walk, read a book, or whatever you think
    > will clear your mind, and then come back and look at it with fresh
    > eyes. I couldn't begin to tell you how many times after I've spent
    > all day fighting with something I've figured it out on the drive home.


    I think most programmers knows that.

    Project managers in panic mode on the other hand ...

    :)

    Arne
    Arne Vajhøj, Nov 8, 2008
    #12
  13. Tom McGlynn

    Roedy Green Guest

    On Sat, 08 Nov 2008 13:32:54 -0800, Patricia Shanahan <>
    wrote, quoted or indirectly quoted someone who said :

    >
    >I sometimes take this a stage further - go to sleep stuck, but wake up
    >knowing the solution. I sometimes wonder how I would manage if I were
    >paid per hour. Obviously, part of my brain was working on the problem
    >overnight...


    Bertrand Russell recommended cramming your head full of all the facts
    of a tough problem then deliberately forgetting about it for a week.
    Come back to it, and often the answer will be sitting there for you
    fully formed.


    I suppose the idea is to impress on your unconscious mind the
    importance of solving the problem, then giving it some time to work,
    without getting too bogged in the details.

    For other strategies, see http://mindprod.com/jgloss/tackling.html

    Newbies very often get focused on one line of a program and stare at
    it and stare at it looking for the error. 99% of the time it is
    somewhere else. Computer programs are highly interlinked. An error
    in one place can manifest somewhere else very commonly.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Your old road is
    Rapidly agin'.
    Please get out of the new one
    If you can't lend your hand
    For the times they are a-changin'.
    Roedy Green, Nov 9, 2008
    #13
    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. Replies:
    2
    Views:
    8,658
    Jim Lewis
    Mar 21, 2006
  2. Juergen Berchtel
    Replies:
    1
    Views:
    5,991
    John C. Bollinger
    May 20, 2005
  3. Soul
    Replies:
    0
    Views:
    519
  4. Pat Maddox
    Replies:
    6
    Views:
    154
    Marcin Mielżyński
    Jan 20, 2006
  5. Igor Nn
    Replies:
    7
    Views:
    435
    Johnny Morrice
    May 28, 2011
Loading...

Share This Page