用于链表的java自定义迭代器

4jb9z9bj  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(573)

对于uni,我们应该自己实现一个字符串链表的迭代器。但是关于如何做到这一点的信息非常少。所以我们自己尝试了一下,在google上搜索了很多,但是我们找到的所有解释都不包括整个代码,我也不知道如何正确地实现迭代器。我认为只要我们使用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;
    }
}
yws3nbqq

yws3nbqq1#

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

相关问题