2009-03-02 177 views
51

鉴于以下代码,我如何迭代类型为ProfileCollection的对象?如何实现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

这篇文章可以帮助你:http://www.yegor256.com/2015/04/30/iterating-adapter.html – yegor256 2015-05-01 21:01:13

回答

58

Iterable是一个通用接口。你可能遇到的一个问题(你没有真正说过你有什么问题,如果有的话)是,如果你使用一个通用的接口/类而没有指定类型参数,你可以擦除不相关的泛型类型在课堂上。一个例子是Non-generic reference to generic class results in non-generic return types

所以我至少将其更改为:

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

,这应该工作:

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

没有对可迭代的类型参数,迭代器可以降低到是Object类型,从而只这将工作:

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

这是Java泛型的一个相当晦涩的角落案例。

如果不是,请提供一些关于正在发生的更多信息。

+5

只是警告你的方法;如果您只是从ArrayList转发迭代器,那么您还可以转发删除项目的功能。如果你不想这样做,你必须包装迭代器,或者将ArrayList作为只读集合包装。 – 2009-03-02 14:37:40

+0

Cletus,谢谢你的解决方案完美。我遇到的问题实际上正是你所描述的。返回类型是Profile的Object instaead,对不起。 嘿贾森,感谢您的评论。我如何包装迭代器? – Dewayne 2009-03-02 15:10:29

4

第一关:

public class ProfileCollection implements Iterable<Profile> { 

二:

return m_Profiles.get(m_ActiveProfile);