如何在Java中进行非破坏性队列检查

时间:2010-02-06 13:28:47

标签: java queue

我正在帮助我的儿子参加大学编程课程,我想我也需要上课。他完成了任务,但我不相信他是最好的方式。不幸的是,我无法以更好的方式工作。它显然更好,因为它还不起作用。

他被要求为扩展另一个类的类实现一些方法。

他被告知必须使用以下类定义,并且他无法在ListQueue中更改任何内容。

public class MyListQueue <AnyType extends Comparable<AnyType>> extends ListQueue<AnyType>

继承人ListQueue中的内容

// Queue interface
//
// ******************PUBLIC OPERATIONS*********************
// void enqueue( x )      --> Insert x
// AnyType getFront( )    --> Return least recently inserted item
// AnyType dequeue( )     --> Return and remove least recent item
// boolean isEmpty( )     --> Return true if empty; else false 
// void makeEmpty( )      --> Remove all items
// ******************ERRORS********************************
// getFront or dequeue on empty queue

/**
 * Protocol for queues.
 */

好的,我觉得穿越Pascal或C中的链表(显示我的年龄)非常好,但以前从未使用过OOP语言。

当我尝试这样的事情时

dummyQueue = this.front.next;

我收到以下错误。 * front在ListQueue *

中拥有私人访问权限

我同意这一点,但除了使项目出列外,我如何遍历列表,或以其他方式访问ListQueue中的前,后,下一个和上一个。

教育将受到赞赏。

谢谢, 大卫

3 个答案:

答案 0 :(得分:2)

如果我理解正确,你就是这样做的:

MyListQueue<String> dummyQueue = new MyListQueue<String>();
dummyQueue = this.front.next;

如果是这样,OOP的主要原则之一是封装,即数据隐藏。这个想法是类外的用户无法访问类的内部状态。

如果您要确定队列的大小并且无法修改接口或实现,那么您可以做的一件事就是创建一个delegate队列来覆盖入队和出队以增加和递减一个柜台。

答案 1 :(得分:1)

如果您决定使用队列,通常只需要将元素排入队列并使其出列。您想知道队列是否为空,并且想要在需要时查看前端元素或将其保留给其他人。如果发送方比接收方快,则队列是一种避免阻塞的缓冲区。使用队列,接收器可以决定何时来读取下一个条目。队列可以实现一些(基于优先级的)排序并决定哪个元素是前面的元素。

如果您需要其他操作,例如遍历列表,那么队列可能不是最佳选择。查看其他集合类型,可能在ArrayList。

虽然可以做一些事情,但你可以继承ListQueue并覆盖一些方法。因此,如果您想要一个额外的size()方法,这可能是一个解决方案:

public class MyListQueue <T extends Comparable<T>> extends ListQueue<T> {

  private size = 0;

  public void enqueue(T element) {
    size++;
    super.enqueue(element);
  }

  public T dequeue() {
    if (isEmpty()) {
       return null; // that's a guess...
    }
    size--;
    super.dequeue(element);
  }

  public int size() {
    return size;
  }
}

我已将AnyType替换为更常见的T。

答案 2 :(得分:0)

你问道,“除了使项目出列外,我如何遍历列表,或以其他方式访问前面,后面,下一页和上一页,这些都在ListQueue中。”

从最纯粹的意义上讲,你不应该这样做。

理想化的队列只承诺一些事情:

  • 项目推送到后面
  • 从前面
  • Pop 项目
  • (可能)检查前面的项目,如果不是空的
  • (可能) pop inspect 定义空间谓词,确定队列是否为空

我现在假设队列不是要与并发读取器(同时访问前端)或并发读取器和写入器(同时访问前端和后端)一起使用。

鉴于该定义,没有理由想要查看队列“内部”。你把东西放在一边,把东西拿出来。如果考虑队列大小的绑定,则可能需要为 push 操作添加一个额外的定义空间谓词,以确定队列是否已满。如果队列有界,“满员”才有意义。如果调用 pop inspect 的线程不希望阻止,则“为空”仅相关。

除此之外,还有一个队列的实用主义思想。我们可以假设它是一系列项目 - 除了并发问题 - 具有可观察的非负大小,甚至可以允许访问序列中的每个项目。有些队列甚至可以在序列前面以外的位置移除或重新排列项目。不过,那时我们不再讨论队列了。我们正在讨论队列的基础序列。如果我们需要这种访问,我们不需要队列。我们需要一个序列,我们希望为程序的其他部分提供类似队列的视图

这就是为什么队列通常不是数据结构库中的具体类型。在C ++中,类型std::queue是围绕其他容器类型的装饰器。在Java中,java.util.Queue是一个接口。 Scala采用不同的方法:类scala.collection.mutable.Queue是类型为MutableList扩展名。这类似于你儿子任务中规定的方法,但不清楚你的ListQueue是否打算允许外人(包括子类)利用其“列表性质” - 穿透队列视图以使用序列内。

您是否有要求除了队列的头部之外还能访问任何其他内容?需要这样做会限制您对消费功能可以容纳的队列类型的选择。看来我们正在通过这项任务学习错误的课程。