簡體   English   中英

在同一個類中實現Java Iterator和Iterable?

[英]Implement Java Iterator and Iterable in same class?

我試圖了解Java IteratorIterable接口

我正在寫這門課

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();
        }
    }   

哪一個更好?

您幾乎應該在同一個類中同時實現IterableIterator 他們做不同的事情。 迭代器自然是有狀態的 - 當你迭代使用它時,它必須更新它的世界觀。 但是,迭代只需要能夠創建新的迭代器。 特別是,您可以讓幾個迭代器同時在同一個原始迭代上工作。

你當前的方法非常好 - 我會改變實施的各個方面,但在責任分離方面卻很好。

你第一次嘗試就走上了正軌。 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM