Como posso implementar a interface Iterable?
Pergunta
Dado o seguinte código, como eu posso iterar sobre um objeto do tipo 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);
}
}
Solução
Iterable é uma interface genérica. Um problema que você pode ter (você não tem realmente disse qual é o problema que você está tendo, se for o caso) é que se você usar um genérico de interface / classe sem especificar o argumento (s) tipo que você pode apagar os tipos de tipos genéricos não relacionados dentro da classe. Um exemplo disto está em referência não-genérico para resultados de classe genéricos em tipos de retorno não-genéricos .
Assim, gostaria de, pelo menos, mude para:
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);
}
}
e isso deve funcionar:
for (Profile profile : m_PC) {
// do stuff
}
Sem o argumento de tipo em Iterable, o iterador pode ser reduzida com o tipo sendo objeto tão somente este trabalho:
for (Object profile : m_PC) {
// do stuff
}
Este é um caso de canto muito obscuro de genéricos Java.
Se não, forneça mais algumas informações sobre o que está acontecendo.
Outras dicas
Primeiro:
public class ProfileCollection implements Iterable<Profile> {
Segundo:
return m_Profiles.get(m_ActiveProfile);