Java的PriorityQueue是不稳定的还是不确定的?

我正在遍历JavaPriorityQueue文档,并遇到了一个重要注意事项:

If multiple elements are tied for least value, the head is one of
those elements — ties are broken arbitrarily

我想了解该粗体字的实际含义.我感兴趣的两个属性是PriorityQueue的稳定性及其确定性.

据我了解,稳定的算法将(摘自*):

preserve the original order of the input set

而确定性算法将(摘自*):

given a particular input, […] produce the same output

这是我的示例:

public class PriorityQueueTest {
    public static class Herp implements Comparable<Herp>{
        int attribute;
        String name;

        Herp(int attribute,String name){
            this.attribute=attribute;
            this.name=name;
        }
        @Override 
        public String toString(){
            return name+": "+attribute;
        }
        @Override
        public int compareTo(Herp o) {
            return Integer.compare(o.attribute, this.attribute);
        }

    }
    public static void main(String[] args){
            PriorityQueue<Herp> queue= new PriorityQueue<Herp>();
            queue.add(new Herp(1,"Fred"));
            queue.add(new Herp(1,"James"));
            queue.add(new Herp(2,"Bob"));
            queue.add(new Herp(3,"Rachel"));
            queue.add(new Herp(4,"Constance"));
            List<Herp> debug= new ArrayList<>();
            while(!queue.isEmpty()){
                debug.add(queue.poll());
            }
            System.out.println(Arrays.toString(debug.toArray()));
    }
}

对我来说,这段代码输出以下内容:

[Constance: 4, Rachel: 3, Bob: 2, Fred: 1, James: 1]

如果我切换弗雷德和詹姆斯的插入顺序,我会得到相同的结果.因此PriorityQueue不稳定.但是,我不能反驳其确定性.无论我尝试哪种插入顺序,无论我运行了多少次代码,Fred总是排在James之前.

但是,我担心这种行为是特定于计算机或JVM的(在我看来,这是不确定的),或者存在一些反例,其输出将有所不同.

另一个可能性是,尽管目前在所有JVM和计算机上的实现可能是确定性的,但未指定此属性,并且将来可能会对其进行更改.

我可以理解内部实现是否基于某种ObjectID或内部内存值打破了束缚,这将使其变得不稳定但具有确定性.但是,它也可以根据系统时间,随机数,月相等来进行.这将使其变得不稳定且不确定.

TLDR:Java的PriorityQueue是否具有确定性?

This question尽管有其名称,但证明了该算法的不稳定性,其答案仅与文档有关,而文档未对确定性做出回应.

解决方法:

它不是稳定的:领带是否被任意打破不可能.这意味着实现可以*选择要首先返回的任何绑定元素.一个稳定的实现必须按绑定元素插入队列的顺序返回它们.

它不一定是确定性的或不确定性的:它可以选择如何任意打破平局,因此它可以确定性地进行操作(即,如果您放入相同的元素,则可以按相同的顺序将它们取出来,不论该顺序是什么)或不确定的方式(即,相同的元素不会以相同的顺序出现).

上一篇:Java中的确定性RSA加密


下一篇:MySQL 错误1418 的原因分析及解决方法