队列接口混乱



问题1:

以下输出为 1,2,3

Queue<Integer> q1 = new PriorityQueue<Integer>();
    q1.add(1);
    q1.add(3);
    q1.add(2);
    System.out.print(pq.poll());
    System.out.print(pq.poll());
    System.out.print(pq.poll());

以下输出为 1,3,2

Queue<Integer> q2 = new LinkedList<Integer>();
    q3.add(1);
    q3.add(3);
    q3.add(2);
    System.out.print(q3.poll());
    System.out.print(q3.poll());
    System.out.print(q3.poll());

为什么?由于它们都在实现队列接口但具有不同的行为?我认为无论实现类是什么,如果它们实现相同的接口,它的行为都必须相同。

问题2:

假设我用以下内容定义一个类

class process {
  int exeTime;
  int arrTime;
  process(int, arr, int exe) {
    arrTime=arr;
    exeTime = exe;
  }
}

在下面的代码行中重写比较方法会产生什么影响,为什么?

PriorityQueue<process> pq2 = new PriorityQueue<process>(new Comparator<process>() {
        @Override
        public int compare(process p1, process p2) {
            if (p1.exeTime == p2.exeTime)
                return p1.arrTime - p2.arrTime;
            return p1.exeTime - p2.exeTime;
        }
    });

完全没有。 阅读Queue接口文档:

队列通常(但不一定)以 FIFO(先进先出)方式对元素进行排序。例外情况包括优先级队列,它根据提供的比较器或元素的自然顺序对元素进行排序,以及LIFO队列(或堆栈),它对元素LIFO(后进先出)进行排序。无论使用什么顺序,队列的头部都是通过调用 remove() 或 poll() 删除的元素。在 FIFO 队列中,所有新元素都插入到队列的尾部。其他类型的队列可能使用不同的放置规则。每个队列实现都必须指定其排序属性。

Queue 的实现可以使用它选择的任何顺序。

2)队列将首先按exeTime排序,如果exeTime有平局,则按arrTime排序。

  1. 是的,这两个类具有不同的行为,但它与Queue接口并不矛盾。

Queue中用于add的Javadocs没有说明任何特定的顺序:

如果

可以在不违反容量限制的情况下立即将指定的元素插入到此队列中,则在成功时返回 true,如果当前没有可用空间,则引发 IllegalStateException。

Queue 中用于poll的 Javadocs 可能会声明它从队列的头部获取,但add没有说明哪个元素应该在队列的头部。

检索并删除此队列的头部,如果此队列为空,则返回 null。

由于Queue没有指定任何特定的顺序,因此每个实现类都可以自由地为自己定义它。

  1. 没有覆盖任何东西;你指定了一个Comparator类,用于根据该构造函数的JavadocsPriorityQueue中的元素进行排序。

创建具有默认初始容量的 PriorityQueue,其元素根据指定的比较器进行排序。

我认为无论实现类是什么,如果它们实现相同的接口,它的行为都必须相同。

这是不正确的。实现所要做的就是满足接口的协定。对于Queue接口,行为可以像堆栈(先进,后出),像传统队列(先进先出),或者基于其他系统的返回元素。

PriorityQueue根据元素的优先级返回元素,由Comparator给出。如果 compare(a, b) 返回负整数,则a的优先级高于 b 。如果compare(a, b)返回一个正整数,则相反。如果compare(a, b)返回0,则ab具有同等的优先级。

最新更新