【问题标题】:I am trying to create a circular LinkedList Please tell me if its a correct way to do it我正在尝试创建一个循环链接列表请告诉我它是否是正确的方法
【发布时间】:2015-02-24 05:46:11
【问题描述】:

我已经实现了逻辑,比如如果我给出一个还没有的索引,那么它会将索引更改为提醒(我猜就像旋转一样)。

import java.util.LinkedList;

public class MycircularlinkedList extends LinkedList {

    private static int count = 0;

    public Object get(int i) {
        System.out.println("count==" + count);
        if (i > count) {
            i = i % count;
            return super.get(i);

        } else {
            return super.get(i);
        }

    }

    public boolean add(Object o) {

        super.add(o);
        count++;
        return true;
    }

    public void add(int i, Object o) {
        if (i > count)
            i = i % count;
        super.add(i, o);
        count++;
    }
}

【问题讨论】:

  • 不需要count,可以用size()

标签: java data-structures linked-list circular-list


【解决方案1】:

我可以看到几点:

  1. count 是静态的,这意味着您在这里只会有一个号码。可能不是你想要的
  2. count 是多余的,使用Collection#size()
  3. mod (%) 的优点在于它适用于所有数字,您不需要有条件。 2 % 12 == 14 % 12 == -10 % 12
  4. 如果您要摆脱 count 属性,您可以摆脱覆盖的 #add(Object o) 逻辑,只需执行 return super.add(o);

【讨论】:

    【解决方案2】:

    我发现您的代码存在一些问题:如果 count ==0 并且如果我使用方法 add(7,obj) ,那么 7%0 将抛出 ArithmeticException.count 应该声明为私有,因为您可能有两个实例你的班级。另外,你需要检查 poll\offerLast 方法是否满足您的需求,因为您无法限制 避免使用它们的任何客户端代码。最后,clone\readObject\writeObject 需要覆盖计数变量。

    【讨论】:

    • Luchy 你说得对,我也看得出来。无论如何,这已经解决了我想展示我的逻辑,这是实现循环链​​表的好方法。谢谢你指出我的错误,我希望将来你也会对我有很大的帮助。
    • 我认为你可以实现自己的循环链表,因为它没有第一个或最后一个节点,但链表有它们。所以在这种情况下,使用继承不是一个好习惯。
    【解决方案3】:

    你已经接近了。

    (1) 众所周知,术语“circular linked list”表示尾部链接回头部的列表(如果它是双向链接列表,反之亦然)。您的更像是存储在链表中的“循环缓冲区”。我们可以称它为LinkedListCircularBuffer 或其他名称。

    (2) 类应该由元素类型参数化,因此

    public class LinkedListCircularBuffer<E> extends LinkedList<E> {
      @Override
      public E get(int i) {
        return super.get(i % size()); // simpler and faster without an "if"
      }
    }
    

    (3) 你可以调用size()而不是所有代码来维护另一个count

    (4) 你的add(int i, Object o) 方法不支持i == size() 的情况,但你可以通过完全不覆盖add() 来解决这个问题。

    (5) 被覆盖的方法需要@Override 注解。

    (6)总是在每个“then”和“else”子句周围加上大括号是一种很好的风格。类似代码

    if (i > count)
      i = i % count;
    

    是脆弱的,例如在“then”子句中添加println() 语句会破坏它。

    【讨论】:

    • 之前想用size,但不知道为什么没用。感谢您的帮助,我会尝试您在这里提出的建议。
    • 我已经尝试了上述建议,显然它应该可以正常工作。但是谁能告诉我任何其他方式(更专业)的方式。
    • 如果这个设计适合你的使用,上面的代码很好。如果您想要一个固定大小的循环缓冲区,请在网上搜索“Java 循环缓冲区”。
    • Java 更正库、Google 的 Guava 库和其他地方还有很多可用的集合类。
    猜你喜欢
    • 1970-01-01
    • 2018-03-10
    • 2020-05-28
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2020-04-22
    相关资源
    最近更新 更多