2009-03-02 29 views
51

Với mã sau đây, làm cách nào tôi có thể lặp lại đối tượng của loại ProfileCollection?Làm cách nào để triển khai giao diện 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

bài viết này có thể giúp bạn: http://www.yegor256.com/2015/04/30/iterating-adapter.html – yegor256

Trả lời

58

Iterable là giao diện chung. Một vấn đề mà bạn có thể gặp phải (bạn không thực sự nói vấn đề bạn đang gặp phải là nếu bạn sử dụng một giao diện chung/lớp mà không chỉ rõ kiểu đối số) bạn có thể xóa các kiểu generic không liên quan trong lớp học. Một ví dụ về điều này là trong Non-generic reference to generic class results in non-generic return types.

Vì vậy, tôi ít nhất sẽ thay đổi nó thành:

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

và điều này sẽ làm việc:

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

Nếu không có đối số kiểu trên Iterable, biến lặp có thể được giảm xuống là kiểu Object vì vậy chỉ thao tác này sẽ hoạt động:

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

Đây là trường hợp góc nhìn khá tối nghĩa của Generics Java.

Nếu không, vui lòng cung cấp thêm một số thông tin về những gì đang diễn ra.

+5

Chỉ là một cảnh báo cho cách tiếp cận của bạn; nếu bạn chỉ chuyển tiếp trình lặp từ ArrayList, bạn cũng chuyển tiếp về khả năng loại bỏ các mục. Nếu bạn không muốn điều đó, bạn phải quấn vòng lặp hoặc bọc ArrayList như một bộ sưu tập chỉ đọc. –

+0

Cletus, cảm ơn giải pháp của bạn hoạt động hoàn hảo. Vấn đề tôi gặp phải chính xác là những gì bạn mô tả. Kiểu trả về là Object instaead của Profile, xin lỗi. Xin chào Jason, cảm ơn vì đã bình luận. Làm thế nào để quấn vòng lặp? – Dewayne

+4

Tôi nghĩ anh ấy đang đề cập đến: Collections.unmodifiableList (m_profiles) .iterator(). Điều này sẽ ngăn chặn người gọi sửa đổi danh sách array – cletus

4

Trước hết:

public class ProfileCollection implements Iterable<Profile> { 

Thứ hai:

return m_Profiles.get(m_ActiveProfile); 
+0

điều gì sai với dòng đầu tiên? bạn có thể chỉnh sửa trong lời giải thích không? của nó rất không rõ ràng những gì là sai. – Chii

+4

ahh, cuối cùng đã nhìn thấy nó, sự phát minh của nó. nhưng những điều trên vẫn còn giữ - chỉ cần đặt vào vấn đề là gì, và sửa chữa là gì, và nó sẽ là một câu trả lời tốt hơn. – Chii

Các vấn đề liên quan