[英]Implement Java Iterator and Iterable in same class?
我試圖了解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
。 他們做不同的事情。 迭代器自然是有狀態的 - 當你迭代使用它時,它必須更新它的世界觀。 但是,迭代只需要能夠創建新的迭代器。 特別是,您可以讓幾個迭代器同時在同一個原始迭代上工作。
你當前的方法非常好 - 我會改變實施的各個方面,但在責任分離方面卻很好。
你第一次嘗試就走上了正軌。 MyClass
只需要實現Iterable<String>
,這反過來要求您提供Iterator<String>
實現以從Iterable<String>.iterator()
。
沒有必要將MyClassIterator
放在MyClass
之外,因為在大多數情況下,您甚至不需要直接使用Iterator<String>
(它在Iterable<String>
上的for .. in ..
語法中隱式使用),並且在所有其他情況下,除非您實際向實現添加其他行為(您可能不需要這樣做),否則接口就足夠了。
以下是我的方法,請參閱內聯評論:
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();
}
};
}
}
你不應該做Myclass implements Iterable<String>,Iterator<String>{
因為迭代器是單用的。 除了列表迭代器之外,沒有辦法將它們返回到開頭。
順便說一下,你可以跳過
MyClass myClass;
public MyClassInterator(MyClass m){
myclass=m;
}
而不是引用
myClass
參考
MyClass.this
你的內部類不是靜態的,所以MyClass.this
將引用創建它的封閉類的實例。
我想這是同時實現Iterable和Iterator的標准方法。
// return list of neighbors of v
public Iterable<Integer> adj(int v) {
return new AdjIterator(v);
}
// support iteration over graph vertices
private class AdjIterator implements Iterator<Integer>, Iterable<Integer> {
private int v;
private int w = 0;
AdjIterator(int v) {
this.v = v;
}
public Iterator<Integer> iterator() {
return this;
}
public boolean hasNext() {
while (w < V) {
if (adj[v][w]) return true;
w++;
}
return false;
}
public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return w++;
}
參考https://algs4.cs.princeton.edu/41graph/AdjMatrixGraph.java.html 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.