2009-03-02 17 views
51

Dado el siguiente código, ¿cómo puedo iterar sobre un objeto de tipo ProfileCollection?¿Cómo puedo implementar la interfaz Iterable?

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

este artículo puede ayudarle a: http://www.yegor256.com/2015/04/30/iterating-adapter.html – yegor256

Respuesta

58

Iterable es una interfaz genérica. Un problema que pueda tener (en realidad, no ha dicho qué problema tiene, si lo tiene) es que si utiliza una interfaz/clase genérica sin especificar el tipo de argumento (s) puede borrar los tipos de tipos genéricos no relacionados dentro de la clase. Un ejemplo de esto es en Non-generic reference to generic class results in non-generic return types.

Así que me gustaría al menos cambiarlo a:

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

y esto debería funcionar:

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

Sin el argumento de tipo de Iterable, el repetidor puede ser reducido a ser el tipo de objeto por lo que sólo esto funcionará:

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

este es un caso bastante oscura esquina de genéricos de Java.

Si no es así, proporcione algo más de información sobre lo que está sucediendo.

+5

Solo una advertencia a su enfoque; si solo reenvía el iterador desde ArrayList, también reenvía la capacidad de eliminar elementos. Si no quiere eso, tendría que ajustar el iterador o ajustar el ArrayList como una colección de solo lectura. –

+0

Cletus, gracias tu solución funciona perfectamente. El problema que estaba teniendo en realidad era exactamente lo que describiste. El tipo de devolución fue Object instaead of Profile, lo siento. Hola Jason, gracias por el comentario. ¿Cómo envuelvo el iterador? – Dewayne

+4

Creo que se está refiriendo a: Collections.unmodifiableList (m_profiles) .iterator(). Esto detendrá a la persona que llama a modificar el arraylist. – cletus

4

En primer lugar:

public class ProfileCollection implements Iterable<Profile> { 

Segundo:

return m_Profiles.get(m_ActiveProfile); 
+0

¿Qué pasa con la primera línea? ¿Puedes editar en una explicación? es muy claro lo que está mal. – Chii

+4

ahh, finalmente lo vi, es la generificación. pero lo de arriba todavía se mantiene - simplemente explica cuál fue el problema, y ​​cuál fue la solución, y sería una mejor respuesta. – Chii

Cuestiones relacionadas