2009-03-02 157 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);