Generics and for each

T

Tom McGlynn

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
 
J

Joshua Cranmer

Tom said:
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>.
 
T

Tom McGlynn

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


Thanks...
I should have realized that such a simple case had to work,
Regards,
 
T

Tom McGlynn

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

Thanks... I should have realized that such a simple case had to work
and I'd made an error somewhere.
Tom
 
L

Lew

Tom said:
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 said:
import java.util.ArrayList;
import java.util.Iterator;

public class Zz implements Iterable

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

// consider using: List said:
    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)
 
T

Tom McGlynn

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
 
R

Roedy Green

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

Mike Schilling

Tom said:
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.
 
J

Joshua Cranmer

Mike said:
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.
 
P

Patricia Shanahan

Joshua said:
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
 
A

Arne Vajhøj

Mike said:
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
 
R

Roedy Green

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

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

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top