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

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

对于uni,我们应该自己实现一个字符串链表的迭代器。但是关于如何做到这一点的信息非常少。所以我们自己尝试了一下,在google上搜索了很多,但是我们找到的所有解释都不包括整个代码,我也不知道如何正确地实现迭代器。我认为只要我们使用for-each循环来使用迭代器,一切都可以正常工作,但是只要我们尝试使用“while(iterator.hasnext){next}”这个东西,它就会停留在链表的第一个元素中。我想我知道这个问题是基于我们总是示例化一个新的迭代器,但我不知道如何实现它。希望有人能帮忙,我真的不知道该怎么办,我什么都试过了。。

  1. import java.util.Iterator;
  2. import java.util.NoSuchElementException;
  3. public class LinkedList implements Iterable<String> {
  4. // ---------- Attributes ----------
  5. private int size = 0;
  6. private Node head = null;
  7. // private Iterator<String> linkedListIterator = this.iterator(); // ??
  8. static class Node {
  9. // ---------- Attributes ----------
  10. private String object;
  11. private Node next;
  12. // ---------- Constructors ----------
  13. public Node(String object, Node node) {
  14. this.object = object;
  15. this.next = node;
  16. }
  17. public Node() {
  18. this(null, null);
  19. }
  20. // ---------- Getter, Setter ----------
  21. public String getElement() {
  22. return this.object;
  23. }
  24. public void setElement(String object) {
  25. this.object = object;
  26. }
  27. public Node getNext() {
  28. return this.next;
  29. }
  30. public void setNext(Node node) {
  31. this.next = node;
  32. }
  33. }
  34. class LinkedListIterator implements Iterator<String> {
  35. // ---------- Attributes ----------
  36. private Node currentNode = null;
  37. private int counter = 0;
  38. // ---------- Constructor ----------
  39. public LinkedListIterator(LinkedList linkedList) {
  40. this.currentNode = linkedList.head;
  41. }
  42. // ---------- Getter, Setter, Methods ----------
  43. public boolean hasNext() {
  44. return this.currentNode != null;
  45. }
  46. public String next() {
  47. if (!this.hasNext()) {
  48. System.out.println("Fehler: ");
  49. throw new NoSuchElementException();
  50. }
  51. String object = this.currentNode.getElement(); // ?
  52. this.currentNode = this.currentNode.getNext();
  53. this.counter++;
  54. return object;
  55. }
  56. public int getCounter() {
  57. return this.counter;
  58. }
  59. }
  60. // ---------- Getter, Setter, Methods ----------
  61. public Node getHead() {
  62. return this.head;
  63. }
  64. public void addFirst(String object) {
  65. // new node as head
  66. Node newNode = new Node(object, this.head);
  67. this.head = newNode;
  68. this.size++;
  69. }
  70. public String getFirst() { //throws ListEmptyException {
  71. if (isEmpty()) {
  72. // throw new ListEmptyException();
  73. }
  74. return this.head.getElement();
  75. }
  76. public String removeFirst() { //throws ListEmptyException {
  77. if (isEmpty()) {
  78. // throw new ListEmptyException();
  79. }
  80. String object = this.head.getElement();
  81. this.head = this.head.getNext();
  82. return object;
  83. }
  84. public boolean isEmpty() {
  85. return this.head == null;
  86. }
  87. public int getSize() {
  88. return this.size;
  89. }
  90. @Override
  91. public Iterator<String> iterator() {
  92. System.out.println("helo");
  93. return new LinkedListIterator(this);
  94. }
  95. public String toString() {
  96. String output = "";
  97. // this is working:
  98. // for (String element: this) {
  99. // output += element + "\n";
  100. // }
  101. while (this.iterator().hasNext()) {
  102. System.out.println(this.iterator().hasNext());
  103. output += this.iterator().next() + "\n";
  104. }
  105. return output;
  106. }
  107. public static void main(String[] args) {
  108. LinkedList ll = new LinkedList();
  109. ll.addFirst("a");
  110. ll.addFirst("b");
  111. ll.addFirst("c");
  112. ll.addFirst("d");
  113. ll.addFirst("e");
  114. System.out.println(ll.toString());
  115. }
  116. }

由此解决的问题
但新的问题是:为什么这是有效的

  1. public String toString() {
  2. String output = "";
  3. Iterator<String> iterator = this.iterator();
  4. while (iterator.hasNext()) {
  5. output += it.next() + "\n";
  6. }
  7. return output;
  8. }

但这不是

  1. public class LinkedList implements Iterable<String> {
  2. private Iterator<String> linkedListIterator = this.iterator();
  3. public String toString() {
  4. String output = "";
  5. while (this.linkedListIterator.hasNext()) {
  6. output += this.linkedListIterator.next() + "\n";
  7. }
  8. return output;
  9. }
  10. }
yws3nbqq

yws3nbqq1#

linkedlistiterator的实现是正确的,问题出在tostring()方法中。调用this.iterator()3次,因此每次都返回linkedlistiterator的新示例。相反,只需调用一次this.interator(),然后使用得到的示例。这样地:

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

关于新问题。
如果你示例化 private Iterator<String> linkedListIterator 属性,每次引用它时都会调用 public Iterator<String> iterator() 方法,您将获得 LinkedListIterator .
你犯的错误和开始时一样。这就是为什么属性只能在方法声明中示例化的一个例子。
请记住,迭代器只能向前移动,如果要重新启动它,必须创建一个新示例。你打电话就是这么做的 this.iterator() .
我建议您使用一些调试工具,以便查看执行的指令
此外,还有一种处理迭代器的设计模式。https://en.wikipedia.org/wiki/iterator_pattern

相关问题