在同一个类中实现 Java Iterator 和 Iterable?
Posted
技术标签:
【中文标题】在同一个类中实现 Java Iterator 和 Iterable?【英文标题】:Implement Java Iterator and Iterable in same class? 【发布时间】:2011-08-15 17:21:35 【问题描述】:我正在尝试理解 Java Iterator
和 Iterable
接口
我正在写这门课
class MyClass implements Iterable<String>
public String[] a = null;
public MyClass(String[] arr)
a = arr;
public MyClassIterator iterator()
return new MyClassIterator(this);
public class MyClassIterator implements Iterator<String>
private MyClass myclass = null;
private int count = 0;
public MyClassIterator(MyClass m)
myclass = m;
public boolean hasNext()
return count < myclass.a.length;
public String next()
int t = count;
count++;
return myclass.a[t];
public void remove()
throw new UnsupportedOperationException();
它似乎正在工作。
我应该有:
Myclass implements Iterable<Stirng>, Iterator<String>
或者我应该把MyClassIterator
放在MyClass
之外
class MyClass implements Iterable<String>
public String[] a = null;
public MyClass(String[] arr)
a = arr;
public MyClassIterator iterator()
return new MyClassIterator(this);
public class MyClassIterator implements Iterator<String>
private MyClass myclass = null;
private int count = 0;
public MyClassIterator(MyClass m)
myclass = m;
public boolean hasNext()
return count < myclass.a.length;
public String next()
int t = count;
count++;
return myclass.a[t];
public void remove()
throw new UnsupportedOperationException();
哪个更好?
【问题讨论】:
为什么你的班级需要两者都做?一般来说,您会实现 Iterable,以便有人可以从您的类中获取 Iterator。 【参考方案1】:您几乎应该从不在同一个类中同时实现Iterable
和Iterator
。他们做不同的事情。迭代器自然是有状态的 - 当您使用它进行迭代时,它必须更新其对世界的看法。然而,一个可迭代对象只需要能够创建新的迭代器。特别是,您可以让多个迭代器同时处理同一个原始可迭代对象。
您当前的方法非常好 - 我会更改实施的某些方面,但在职责分离方面很好。
【讨论】:
谢谢,我更新了一点我的问题,哪个更好,将 MyClassInterator 放在 MyClass 之外怎么样? @icn:将 MyClassIterator 保留为嵌套类很好。 (尽管是迭代器,而不是交互器。)我建议您将其设为私有静态最终类。毕竟,您不需要能够直接从其他任何地方引用它。 @icn:您应该将MyClassIterator
保留在MyClass
中。您还应该将其设为private
并使该方法返回Iterator<String>
。您也不应该将MyClass
传递给构造函数,因为MyClassIterator
是一个内部类,并且隐式引用了MyClass
的周围实例,因此您可以直接在其中访问数组a
。跨度>
@Jon - 为什么要将内部类设为静态?
@Jon: Iterator
s 通常(包括在这种情况下)非常适合非静态内部类。他没有使用对外部类的隐式引用,但是……他应该使用! =)【参考方案2】:
您的第一次尝试已步入正轨。 MyClass
只需要实现Iterable<String>
,这反过来需要你提供一个Iterator<String>
实现来从Iterable<String>.iterator()
返回。
没有必要将MyClassIterator
放在MyClass
之外,因为在大多数情况下,您甚至不需要直接使用Iterator<String>
(for .. in ..
上的for .. in ..
语法隐式使用它),在所有其他情况下,接口就足够了,除非您实际上向实现添加了其他行为(您可能永远不需要这样做)。
这是我的做法,请参阅内联的 cmets:
import java.util.Iterator;
class MyClass implements Iterable<String>
public String[] a=null; //make this final if you can
public MyClass(String[] arr)
a=arr; //maybe you should copy this array, for fear of external modification
//the interface is sufficient here, the outside world doesn't need to know
//about your concrete implementation.
public Iterator<String> iterator()
//no point implementing a whole class for something only used once
return new Iterator<String>()
private int count=0;
//no need to have constructor which takes MyClass, (non-static) inner class has access to instance members
public boolean hasNext()
//simplify
return count < a.length;
public String next()
return a[count++]; //getting clever
public void remove()
throw new UnsupportedOperationException();
;
【讨论】:
谢谢,因为我们有一个异常“throw new UnsupportedOperationException();”,所以我们应该在程序的某个地方指定要抛出的异常,比如 throw UnsupportedOperationException()? 欢迎您,@icn。是的,在iterator()
的 cmets 中提及它可能就足够了。实际上,这并不重要,for .. in ..
几乎是唯一在(现代)Java 中直接使用Iterator
s 的构造,它不会尝试使用remove
。事实上,像remove
这样的“可选”接口成员充其量是没有用的,因为消费者几乎不得不假设他们会扔掉。【参考方案3】:
您不应该使用Myclass implements Iterable<String>,Iterator<String>
,因为迭代器是一次性使用的。除了列表迭代器之外,没有办法将它们返回到开头。
顺便说一句,你可以跳过
MyClass myClass;
public MyClassInterator(MyClass m)
myclass=m;
而不是引用
myClass
参考
MyClass.this
您的内部类不是静态的,因此MyClass.this
将引用创建它的封闭类的实例。
【讨论】:
以上是关于在同一个类中实现 Java Iterator 和 Iterable?的主要内容,如果未能解决你的问题,请参考以下文章