为了账号安全,请及时绑定邮箱和手机立即绑定

如何克隆循环链接列表

如何克隆循环链接列表

Helenr 2022-05-21 20:09:29
我正在尝试以与克隆单数链表相同的方式克隆循环链表,但遇到了麻烦。我试图在公共方法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() 返回空列表时,程序不会抛出此异常。
查看完整描述

1 回答

?
智慧大石

TA贡献1946条经验 获得超3个赞

这是问题所在,我认为:

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

现在你还没有告诉我们超类CircularlyLinkedList是什么,但证据是:

  1. 它不实现Cloneable标记接口。

  2. 它不会覆盖clone它继承自的方法Object

使用该组合,super.clone()将抛出CloneNotSupportedException. 这在javadoc中进行了解释。


真正的问题是你为什么打电话super.clone()

如果您这样做是因为超类具有需要在您正在创建的克隆中复制的状态,那么它(超类)必须提供某种克隆自身的方式;即它需要执行上述操作之一……或提供“复制构造函数”或类似内容。

如果您这样做只是为了使打字工作,那么您可能应该这样做:

    CircularlyLinkedList<E> other = new CircularlyLinkedList<>();

构造函数(private如果需要的话可以)创建一个实例,您可以开始填写。请注意,这是类型安全的。


我注意到这条评论:

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

如果它的意思是永远适用于这个类,那么只需修复它以匹配您实际所做的事情。请记住,只有在超类是可克隆的情况下您才能做到……目前还不是!

如果打算记录在所有情况下都这样做 是“最佳实践”(或其他东西;请参阅this ),那是完全错误的:

  • 正如我解释的那样,你不能在所有情况下都这样做。

  • 虽然有人认为使用另一种方法来复制超类状态可能是不可取的,但子类有权在 OO 设计中对其超类做出假设。

  • 此外,打电话给super.clone()你是在做一个假设……这clone()会奏效!


查看完整回答
反对 回复 2022-05-21
  • 1 回答
  • 0 关注
  • 117 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号