簡體   English   中英

用於鏈表的 Java 自定義迭代器

[英]Java custom iterator for linked list

對於 uni,我們應該自己為 String 鏈表實現迭代器。 但是關於如何做到這一點的信息非常少。 所以我們自己嘗試了它並用谷歌搜索了很多,但我們發現的所有解釋都沒有包含整個代碼,我不知道如何正確實現迭代器。 我認為只要我們使用 for each 循環來使用迭代器,一切都可以正常工作,但是一旦我們嘗試使用“while (iterator.hasnext) { next }”,它就會停留在鏈表的第一個元素中. 我想我知道這個問題是基於我們總是實例化一個新的迭代器,但我不知道如何實現它。 希望有人可以提供幫助,我真的不知道該怎么辦,我嘗試了一切..

import java.util.Iterator;
import java.util.NoSuchElementException;

public class LinkedList implements Iterable<String> {

     // ---------- Attributes ---------- 

     private int size = 0;
     private Node head = null;
     // private Iterator<String> linkedListIterator = this.iterator(); // ??

     static class Node {
    
        // ---------- Attributes ---------- 
    
        private String object;
        private Node next;
    
        // ---------- Constructors ---------- 
    
        public Node(String object, Node node) {
             this.object = object; 
             this.next = node;
        }
    
        public Node() { 
            this(null, null); 
        }
    
        // ---------- Getter, Setter ---------- 
    
        public String getElement() { 
            return this.object; 
        }
    
        public void setElement(String object) { 
            this.object = object; 
        }
    
        public Node getNext() { 
            return this.next; 
        }
    
        public void setNext(Node node) { 
            this.next = node; 
        }
    }

    class LinkedListIterator implements Iterator<String> {

        // ---------- Attributes ---------- 

        private Node currentNode = null;
        private int counter = 0;

        // ---------- Constructor ---------- 

        public LinkedListIterator(LinkedList linkedList) {
            this.currentNode = linkedList.head;
        }

        // ---------- Getter, Setter, Methods ---------- 

        public boolean hasNext() {
            return this.currentNode != null;
        }

        public String next() {
            if (!this.hasNext()) {
                System.out.println("Fehler: ");
                throw new NoSuchElementException();
            }

            String object = this.currentNode.getElement(); // ?
            this.currentNode = this.currentNode.getNext();
            this.counter++;
        
            return object;
        }
    
        public int getCounter() {
            return this.counter;
        }

    }

    // ---------- Getter, Setter, Methods ---------- 

    public Node getHead() {
        return this.head;
    }

    public void addFirst(String object) {
        // new node as head
        Node newNode = new Node(object, this.head);
        this.head = newNode;    
        this.size++;
    }

    public String getFirst() { //throws ListEmptyException {
        if (isEmpty()) {
            //      throw new ListEmptyException();
        }
        return this.head.getElement();
    }

    public String removeFirst() { //throws ListEmptyException {
        if (isEmpty()) {
            //      throw new ListEmptyException();
        }

        String object = this.head.getElement();
        this.head = this.head.getNext();
        return object;
    }

    public boolean isEmpty() {
        return this.head == null;
    }

    public int getSize() {
        return this.size;
    }

    @Override
    public Iterator<String> iterator() {
        System.out.println("helo");
        return new LinkedListIterator(this);
    }

    public String toString() {
        String output = "";

    //      this is working:
    //      for (String element: this) {
    //          output += element + "\n";
    //      }
    
        while (this.iterator().hasNext()) {
            System.out.println(this.iterator().hasNext());
            output += this.iterator().next() + "\n";
        }
    
        return output;
    }

    public static void main(String[] args) {
        LinkedList ll = new LinkedList();
        ll.addFirst("a");
        ll.addFirst("b");
        ll.addFirst("c");
        ll.addFirst("d");
        ll.addFirst("e");       
    
        System.out.println(ll.toString());
    }

}

問題由此解決

但新問題:為什么這有效

public String toString() {
    String output = "";
    Iterator<String> iterator = this.iterator();

    while (iterator.hasNext()) {
        output += it.next() + "\n";
    }
    return output;
}

但這不是

public class LinkedList implements Iterable<String> {

    private Iterator<String> linkedListIterator = this.iterator();

    public String toString() {
        String output = "";
    
        while (this.linkedListIterator.hasNext()) {
            output += this.linkedListIterator.next() + "\n";
        }
        return output;
    }
}

您對 LinkedListIterator 的實現是正確的,問題出在 toString() 方法中。 您調用 this.iterator() 3 次,因此每次都返回 LinkedListIterator 的一個新實例。 相反,您只需調用 this.interator() 一次並使用您獲得的實例。 像這樣:

    Iterator<String> it=this.iterator();
    while (it.hasNext()) {
    System.out.println(it.hasNext());
    output += it.next() + "\n";
    }

關於新問題。
如果你在類的主體中實例化private Iterator<String> linkedListIterator屬性,(一些永遠不應該做的事情),每次你引用它時你都會調用public Iterator<String> iterator()方法和您將獲得LinkedListIterator的新實例。
你犯了和一開始一樣的錯誤。 這是一個為什么屬性應該只在方法聲明中實例化的例子。
請記住,迭代器只能向前移動,如果要重新啟動它,則必須創建一個新實例。 這就是你通過調用this.iterator()所做的。
建議你使用一些調試工具,這樣你就可以看到執行的指令
此外,還有一種處理迭代器的設計模式。 https://en.wikipedia.org/wiki/Iterator_pattern

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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