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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21512250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:04:58  来源:igfitidea点击:

How can I make my class iterable so I can use foreach syntax?

javaforeachiterable

提问by mk_

I have Bookand BookListclasses. BookListis something like this:

我有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) { ... }

}

In my main class I want to print titles of books with in a for each loop:

在我的主课中,我想在每个循环中打印书名:

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

Eclipse says:

Eclipse 说:

Can only iterate over an array or an instance of java.lang.Iterable

只能迭代数组或 java.lang.Iterable 的实例

How can I get this working?

我怎样才能让它工作?

采纳答案by andersschuller

You need to implement the Iterableinterface, which means you need to implement the iterator()method. In your case, this might look something like this:

你需要实现Iterable接口,这意味着你需要实现iterator()方法。在您的情况下,这可能如下所示:

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

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

    ...
}

回答by Alden

To be more specific about how to "implement the Iterableinterface":

更具体地说明如何“实现Iterable接口”:

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

    ... 

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

回答by Stephen C

Implement the Iterableinterface. That means you need to implement a method that returns an Iteratorobject that will iterate over the elements of a BookList.

实现Iterable接口。这意味着您需要实现一个方法来返回一个Iterator对象,该对象将迭代 a 的元素BookList

In this case, your iterator()method could just return the result of calling bList.iterator(). (That will cause for (Book b : somBookList)to iterate over the Bookobjects in the BookList.bList... )

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

In other cases, you might need to write your own Iterator<T>implementation class, complete with T next(), boolean hasNext()and remove()methods. For instance, if you wanted to prevent external code from removing elements from the BookListvia your iterator, you might implement it like this:

在其他情况下,您可能需要编写自己的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");
            }
        };
    }
}

回答by JDGuide

For making a class iteratable you need to implement IterableInterface.

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

a) Declare the class as below

a) 声明类如下

public class BookList implements Iterable<Book>

b) Override the iterator()Method

b) 覆盖iterator()方法

Read More. Hope it will help you.

阅读更多。希望它会帮助你。

回答by user3531588

Here we can see the simple implementation of LinkedList with iterator and foreach syntax

在这里我们可以看到使用迭代器和 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());
        }
    }
}