猿问

如何克隆循环链接列表

我正在尝试以与克隆单数链表相同的方式克隆循环链表,但遇到了麻烦。


我试图在公共方法clone()中只留下调用受保护方法clone()的行,但程序仍然抛出错误。


public static void main(String[] args) throws CloneNotSupportedException 

  {


  CircularlyLinkedList<String> circularList = new 

  CircularlyLinkedList<String>();

  circularList.addFirst("1");

  circularList.addLast("2");

  circularList.addLast("3");

  circularList.addLast("4");



  CircularlyLinkedList<String> newList = new CircularlyLinkedList<String>();

  newList= circularList.clone();

  System.out.println(newList);

  }

@SuppressWarnings("unchecked")

public CircularlyLinkedList<E> clone() throws CloneNotSupportedException 

{

  // always use inherited Object.clone() to create the initial copy

    CircularlyLinkedList<E> other = (CircularlyLinkedList<E>) super.clone(); // safe cast

    if (size > 0) {                    // we need independent chain of nodes

        other.head = new Node<>(head.getElement(), null);

        Node<E> walk = head.getNext();      // walk through remainder of original list

        Node<E> otherTail = other.head;     // remember most recently created node

        while (walk != null) {              // make a new node storing same element

          Node<E> newest = new Node<>(walk.getElement(), null);

          otherTail.setNext(newest);     // link previous node to this one

          otherTail = newest;

          walk = walk.getNext();

        }

      }

    return other;

}


此代码在使用单链表时有效。预期的输出是打印两次的链表,但实际输出的是抛出的异常“CloneNotSupported”。请注意,当 clone() 返回空列表时,程序不会抛出此异常。


Helenr
浏览 118回答 1
1回答

智慧大石

这是问题所在,我认为:CircularlyLinkedList<E>&nbsp;other&nbsp;=&nbsp;(CircularlyLinkedList<E>)&nbsp;super.clone();现在你还没有告诉我们超类CircularlyLinkedList是什么,但证据是:它不实现Cloneable标记接口。它不会覆盖clone它继承自的方法Object。使用该组合,super.clone()将抛出CloneNotSupportedException.&nbsp;这在javadoc中进行了解释。真正的问题是你为什么打电话super.clone()?如果您这样做是因为超类具有需要在您正在创建的克隆中复制的状态,那么它(超类)必须提供某种克隆自身的方式;即它需要执行上述操作之一……或提供“复制构造函数”或类似内容。如果您这样做只是为了使打字工作,那么您可能应该这样做:&nbsp;&nbsp;&nbsp;&nbsp;CircularlyLinkedList<E>&nbsp;other&nbsp;=&nbsp;new&nbsp;CircularlyLinkedList<>();构造函数(private如果需要的话可以)创建一个实例,您可以开始填写。请注意,这是类型安全的。我注意到这条评论://&nbsp;always&nbsp;use&nbsp;inherited&nbsp;Object.clone()&nbsp;to&nbsp;create&nbsp;the&nbsp;initial&nbsp;copy如果它的意思是永远适用于这个类,那么只需修复它以匹配您实际所做的事情。请记住,只有在超类是可克隆的情况下您才能做到……目前还不是!如果打算记录在所有情况下都这样做 是“最佳实践”(或其他东西;请参阅this ),那是完全错误的:正如我解释的那样,你不能在所有情况下都这样做。虽然有人认为使用另一种方法来复制超类状态可能是不可取的,但子类有权在 OO 设计中对其超类做出假设。此外,打电话给super.clone()你是在做一个假设……这clone()会奏效!
随时随地看视频慕课网APP

相关分类

Java
我要回答