如何使我的类可迭代,以便我可以使用foreach语法?

时间:2014-02-02 15:20:45

标签: java foreach iterable

我有BookBookList个类。 BookList是这样的:

public class BookList 
{
    private final List<Book> bList = new ArrayList<Book>();

    public int size() { return bList.size(); }

    public boolean isEmpty() {  ... }

    public boolean contains(Book b) { ...  }

    public boolean add(Book b) { ...  }

    public boolean remove(Book b) {  .. } 

    public void clear() { ... }

    public Object get(int index) { ... }

}

在我的主要课程中,我想在每个循环中打印书籍标题:

for(Book b : bList)
{
    b.print();
}

Eclipse说:

  

只能遍历数组或java.lang.Iterable

的实例

我怎样才能使这个工作?

5 个答案:

答案 0 :(得分:28)

您需要实现Iterable接口,这意味着您需要实现iterator()方法。在您的情况下,这可能看起来像这样:

public class BookList implements Iterable<Book> {
    private final List<Book> bList = new ArrayList<Book>();

    @Override
    public Iterator<Book> iterator() {
        return bList.iterator();
    }

    ...
}

答案 1 :(得分:24)

实施Iterable界面。这意味着您需要实现一个返回Iterator对象的方法,该对象将遍历BookList的元素。

在这种情况下,您的iterator()方法只能返回调用bList.iterator()的结果。 (这将导致for (Book b : somBookList)迭代Book中的BookList.bList个对象...)

在其他情况下,您可能需要编写自己的Iterator<T>实施类,并使用T next()boolean hasNext()remove()方法。例如,如果您想阻止外部代码通过迭代器从BookList中删除元素,您可以像这样实现它:

public class BookList implements Iterable<Book> {
    private final List<Book> bList = new ArrayList<Book>();
    //...
    @Override
    public Iterator<Book> iterator() {
        return new Iterator<Book> () {
            private final Iterator<Book> iter = bList.iterator();

            @Override
            public boolean hasNext() {
                return iter.hasNext();
            }

            @Override
            public Book next() {
                return iter.next();
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("no changes allowed");
            }
        };
    }
}

答案 2 :(得分:7)

在这里,我们可以看到使用iterator和foreach语法

的LinkedList的简单实现
class LinkedList implements Iterable<LinkedList.Node>{
    private Node node;
    public void add(Object data){
        if(!Optional.ofNullable(node).isPresent()){
            node = new Node();
            node.setData(data);
        }else{
            Node node = new Node();
            node.setData(data);
            Node lastNode = getLastNode(this.node);
            lastNode.setNext(node);
        }
    }

    private Node getLastNode(Node node){
        if(node.getNext()==null){
            return node;
        }else{
            return getLastNode(node.getNext());
        }
    } 

    class Node{
        private Object data;
        private Node next;
        public Object getData() {
            return data;
        }
        public void setData(Object data) {
            this.data = data;
        }
        public Node getNext() {
            return next;
        }
        public void setNext(Node next) {
            this.next = next;
        }
    }

    public Iterator<Node> iterator() {
        return new NodeIterator();
    }

    class NodeIterator implements Iterator<Node>{
        private Node current;

        public boolean hasNext() {
            if(current == null){
                current = node;
                return Optional.ofNullable(current).isPresent();
            }else{
                current = current.next;
                return Optional.ofNullable(current).isPresent();
            }
        }

        public Node next() {
            return current;
        }
    }
}

public class LinkedListImpl {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add("data1");
        linkedList.add("data2");
        linkedList.add("data3");
        for(LinkedList.Node node: linkedList){
            System.out.println(node.getData());
        }
    }
}

答案 3 :(得分:2)

更具体地说明如何“实施Iterable界面”:

public class BookList implements Iterable<Book>
{
    private final List<Book> bList = new ArrayList<Book>();

    ... 

    @Override
    public Iterator<Book> iterator()
    {
        return bList.iterator();
    }
}

答案 4 :(得分:1)

为了使类可迭代,您需要实现Iterable接口。

a)将类声明如下

public class BookList implements Iterable<Book>

b)覆盖iterator()方法

Read More。 希望它会对你有所帮助。