如何使我的类可迭代,以便我可以使用 foreach 语法?
Posted
技术标签:
【中文标题】如何使我的类可迭代,以便我可以使用 foreach 语法?【英文标题】:How can I make my class iterable so I can use foreach syntax? 【发布时间】:2014-02-26 01:08:03 【问题描述】:我有 Book
和 BookList
课程。 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 Book get(int index) ...
在我的主课中,我想在 for each 循环中打印书名:
for(Book b : bList)
b.print();
Eclipse 说:
只能遍历数组或 java.lang.Iterable 的实例
我怎样才能让它工作?
【问题讨论】:
你需要实现那个接口。 尝试实现Iterable
接口。
你在一个简单的 Listadd(Object)
方法而不是 add(Book)
。你需要实现Iterable
接口,也就是说你需要实现iterator()
方法。在您的情况下,这可能看起来像这样:
public class BookList implements Iterable<Book>
private final List<Book> bList = new ArrayList<Book>();
@Override
public Iterator<Book> iterator()
return bList.iterator();
...
【讨论】:
【参考方案2】:实现Iterable
接口。这意味着您需要实现一个返回 Iterator
对象的方法,该对象将遍历 BookList
的元素。
在这种情况下,您的iterator()
方法可能只返回调用bList.iterator()
的结果。 (这将导致for (Book b : somBookList)
遍历BookList.bList
中的Book
对象...)
在其他情况下,您可能需要编写自己的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");
;
【讨论】:
┼1 用于“其他情况”部分。【参考方案3】:这里我们可以看到使用迭代器和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());
【讨论】:
【参考方案4】:更具体地说明如何“实现Iterable
接口”:
public class BookList implements Iterable<Book>
private final List<Book> bList = new ArrayList<Book>();
...
@Override
public Iterator<Book> iterator()
return bList.iterator();
【讨论】:
请注意,这将允许调用者在不通过破坏封装的 BookList.remove() 方法的情况下删除书籍。你最好用return Collections.unmodifiableList(bList).iterator();
【参考方案5】:
要使类可迭代,您需要实现Iterable
接口。
a) 如下声明类
public class BookList implements Iterable<Book>
b) 覆盖iterator()
方法
Read More。 希望对你有帮助。
【讨论】:
以上是关于如何使我的类可迭代,以便我可以使用 foreach 语法?的主要内容,如果未能解决你的问题,请参考以下文章