如何将我自己的链表中的迭代器定义为 Java 中的节点?

Posted

技术标签:

【中文标题】如何将我自己的链表中的迭代器定义为 Java 中的节点?【英文标题】:How can I define the iterator in my own linked list to be a Node in Java? 【发布时间】:2022-01-05 17:33:20 【问题描述】:

我想在我自己的链表中为带有 Consumer 的 foreach 方法实现 Iterable 接口,但我不知道如何使 next() 方法返回 Node 而不是泛型类型。我知道通常你会希望迭代器是存储在节点内的数据类型,但我希望它是节点本身以获得更大的灵活性。总的来说,我对泛型和 Java 还很陌生。

这是我课程的相关部分。此外,这里还有一些并不真正感兴趣的添加和删除方法。

import java.util.Iterator;

class OwnList<Type> implements Iterable<T>

    class Node
        Type data;
        Node next;

        public Node(Type data, Node next)
            this.data = data;
            this.next = next;
        
    

    Node head;

    @Override
    public <T> Iterator<T> iterator()
        Iterator<T> iterator = new Iterator<T>()
            private Node index = head;

            @Override
            public boolean hasNext()
                return index.next == null ? false : true;
            

            @Override
            public T next()
                return index = index.next;
            

            @Override
            public void remove()

            
        ;
        return iterator;
    

【问题讨论】:

这能回答你的问题吗? Implementing custom Iterator on a LinkedList 如果你希望它遍历Node,那么你应该实现Iterable&lt;Node&gt;,并返回一个Iterator&lt;Node&gt; 【参考方案1】:

我把它分成 2 个类,而不是把它们全部混为一个。

Node.java

public class Node<T>


   private T data;
   private Node<T> next;

   public Node(T data, Node<T> next)
   
   
      this.data = data;
      this.next = next;
   
   
   
   public Node<T> next()
   
   
      return this.next;
   
   
   

NodeList.java

import java.util.Iterator;

public class NodeList<T> implements Iterable<Node<T>>

   private Node<T> head;

   @Override
   public Iterator<Node<T>> iterator()
   
      
      return 
         new Iterator<Node<T>>()
         
         
            private Node<T> index = head;
         
            @Override
            public boolean hasNext()
            
               return index.next() == null ? false : true;
            
         
            @Override
            public Node<T> next()
            
               return index = index.next();
            
         
            @Override
            public void remove()
            
            
            
         ;
   
   
   

EDIT - 找到了另一种重写 Node.java 的方法。好处是它的代码少了很多。唯一的问题是您的数据现在是 shallowly immutable。此外,这仅适用于 Java 14 或更高版本。

Node.java - 重做

import java.util.Iterator;

public record Node<T>(T data, Node<T> next)


   public Node(Node<T> node)
   
   
      this(node.data, node.next);
   
   


此外,您无需对 NodeList.java 进行任何更改 - 您只需切换出 Node.java 即可使用此不可变版本。

【讨论】:

以上是关于如何将我自己的链表中的迭代器定义为 Java 中的节点?的主要内容,如果未能解决你的问题,请参考以下文章

如何从java中的链表中删除一个对象?

OpenHarmony中的HDF单链表及其迭代器

如何将数据动态存储在C中的链表中?

迭代LeetCode 82. 删除排序链表中的重复元素 II

LeetCode 21.合并两个有序链表

LeetCode 138. 复制带随机指针的链表(Map,复制链表,Java)