How can I implement the Iterable interface?

JavaIterator

Java Problem Overview


Given the following code, how can I iterate over an object of type ProfileCollection?

public class ProfileCollection implements Iterable {    
    private ArrayList<Profile> m_Profiles;
    
    public Iterator<Profile> iterator() {        
        Iterator<Profile> iprof = m_Profiles.iterator();
        return iprof; 
    }
 
    ...

    public Profile GetActiveProfile() {
        return (Profile)m_Profiles.get(m_ActiveProfile);
    }
}

public static void main(String[] args) {
     m_PC = new ProfileCollection("profiles.xml");

     // properly outputs a profile:
     System.out.println(m_PC.GetActiveProfile()); 

     // not actually outputting any profiles:
     for(Iterator i = m_PC.iterator();i.hasNext();) {
        System.out.println(i.next());
     }

     // how I actually want this to work, but won't even compile:
     for(Profile prof: m_PC) {
        System.out.println(prof);
     }
}

Java Solutions


Solution 1 - Java

Iterable is a generic interface. A problem you might be having (you haven't actually said what problem you're having, if any) is that if you use a generic interface/class without specifying the type argument(s) you can erase the types of unrelated generic types within the class. An example of this is in Non-generic reference to generic class results in non-generic return types.

So I would at least change it to:

public class ProfileCollection implements Iterable<Profile> { 
    private ArrayList<Profile> m_Profiles;

    public Iterator<Profile> iterator() {        
        Iterator<Profile> iprof = m_Profiles.iterator();
        return iprof; 
    }

    ...

    public Profile GetActiveProfile() {
        return (Profile)m_Profiles.get(m_ActiveProfile);
    }
}

and this should work:

for (Profile profile : m_PC) {
    // do stuff
}

Without the type argument on Iterable, the iterator may be reduced to being type Object so only this will work:

for (Object profile : m_PC) {
    // do stuff
}

This is a pretty obscure corner case of Java generics.

If not, please provide some more info about what's going on.

Solution 2 - Java

First off:

public class ProfileCollection implements Iterable<Profile> {

Second:

return m_Profiles.get(m_ActiveProfile);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDewayneView Question on Stackoverflow
Solution 1 - JavacletusView Answer on Stackoverflow
Solution 2 - JavaTofuBeerView Answer on Stackoverflow