当前位置:  开发笔记 > 编程语言 > 正文

我如何使用PriorityQueue?

如何解决《我如何使用PriorityQueue?》经验,为你挑选了7个好方法。

我如何得到一个PriorityQueue排序我希望它排序的东西?

另外,offeradd方法之间有区别吗?



1> Jon Skeet..:

使用构造函数重载,它接受Comparator comparator并传入比较器,该比较器以适当的方式比较排序顺序.如果您举一个如何排序的示例,我们可以提供一些示例代码来实现比较器,如果您不确定的话.(虽然这很简单.)

正如其他地方所说的那样:offer并且add只是不同的接口方法实现.在JDK源码中,我有add电话offer.虽然add并且由于能够指示由于大小限制而不能添加该值而通常offer具有可能不同的行为offer,但是这种差异是无关紧要的PriorityQueue.

以下是按字符串长度排序的优先级队列的示例:

// Test.java
import java.util.Comparator;
import java.util.PriorityQueue;

public class Test {
    public static void main(String[] args) {
        Comparator comparator = new StringLengthComparator();
        PriorityQueue queue = new PriorityQueue(10, comparator);
        queue.add("short");
        queue.add("very long indeed");
        queue.add("medium");
        while (queue.size() != 0) {
            System.out.println(queue.remove());
        }
    }
}

// StringLengthComparator.java
import java.util.Comparator;

public class StringLengthComparator implements Comparator {
    @Override
    public int compare(String x, String y) {
        // Assume neither string is null. Real code should
        // probably be more robust
        // You could also just return x.length() - y.length(),
        // which would be more efficient.
        if (x.length() < y.length()) {
            return -1;
        }
        if (x.length() > y.length()) {
            return 1;
        }
        return 0;
    }
}

这是输出:

介质

确实很长


`compare`实现不应该是`return x.length() - y.length()`?(避免分支预测)
嗯......刚刚注意到...... priorityQueue.comparator()"返回用于对此集合进行排序的比较器,如果此集合根据其元素的自然顺序(使用Comparable)进行排序,则返回null." 这是否意味着我可以在我的班级上实现Comparable?
@Franky:可能是,是的 - 尽管我会说*稍微难以理解,答案的目的是证明它是如何工作的.我会添加评论.
你可以,是的.我不会这样做,除非你的班级有一个自然的排序顺序.如果有的话,那是正确的做法:)
@KarelG:只要你意识到差异,我就不会认为这太重要了.我想如果你使用`add()`进行添加操作,那么`remove()`感觉很合理; 如果我使用`offer()`我可能会使用`poll()`...但这只是个人偏好.

2> i_am_zero..:

Java 8解决方案

我们可以在Java 8中使用lambda expressionmethod reference引入.如果我们在Priority Queue中存储了一些String值,我们可以提供内联比较器(基于String的长度):

使用lambda表达式

PriorityQueue pq=
                    new PriorityQueue(5,(a,b) -> a.length() - b.length());

使用方法参考

PriorityQueue pq=
                new PriorityQueue(5, Comparator.comparing(String::length));

然后我们可以使用它们中的任何一个:

public static void main(String[] args) {
        PriorityQueue pq=
                new PriorityQueue(5, (a,b) -> a.length() - b.length());
       // or pq = new PriorityQueue(5, Comparator.comparing(String::length));
        pq.add("Apple");
        pq.add("PineApple");
        pq.add("Custard Apple");
        while (pq.size() != 0)
        {
            System.out.println(pq.remove());
        }
    }

这将打印:

Apple
PineApple
Custard Apple

要反转顺序(将其更改为最大优先级队列),只需更改内联比较器中的顺序.

offer()vs add()

根据文件

如果可能,offer方法插入一个元素,否则返回false.这与Collection.add方法不同,后者只能通过抛出未经检查的异常来添加元素.offer方法设计用于故障是正常而非异常发生时,例如,在固定容量(或"有界")队列中.

使用容量限制队列时,offer()通常优于add(),只能通过抛出异常来插入元素.而PriorityQueue中是一个基于优先级堆的极大优先级队列.



3> dragonfly..:

只需传递Comparator给构造函数:

PriorityQueue(int initialCapacity, Comparator comparator)

offer和之间的唯一区别add是它们所属的界面.offer属于Queue,而add最初在Collection界面中看到.除此之外,两种方法完全相同 - 将指定的元素插入优先级队列.


具体来说,如果容量限制阻止将项目添加到队列,而offer返回false,则add()会抛出异常.由于PriorityQueues没有最大容量,因此差异没有实际意义.

4> Peter..:

来自Queue API:

如果可能,offer方法插入一个元素,否则返回false.这与Collection.add方法不同,后者只能通过抛出未经检查的异常来添加元素.offer方法设计用于故障是正常而非异常发生时,例如,在固定容量(或"有界")队列中.



5> d1ck50n..:

没有什么不同,如在javadoc中声明:

public boolean add(E e) {
    return offer(e);
}



6> Blueriver..:

只是为了回答add()vs offer()问题(因为另一个完全回答了imo,这可能不是):

根据接口Queue上的JavaDoc,"offer方法尽可能插入一个元素,否则返回false.这与Collection.add方法不同,Collection.add方法只能通过抛出未经检查的异常来添加元素.refer方法是为当故障是正常而非异常发生时使用,例如,在固定容量(或"有界")队列中."

这意味着如果你可以添加元素(在PriorityQueue中应该总是这样),它们的工作方式完全相同.但是,如果你不能添加元素,offer()将给你一个漂亮而漂亮的false返回,同时add()抛出一个你不想在你的代码中讨厌的未经检查的异常.如果添加失败意味着代码按预期工作和/或它是您正常检查的内容,请使用offer().如果添加失败意味着某些内容被破坏,请add()根据Collection接口的规范使用和处理抛出的结果异常.

它们都实现这种方式来fullfill队列接口来指定在合同offer()通过返回失败false(方法在容量限制的队列优选),并且还保持了Collection接口,关于合同指定add()总是通过抛出异常失败.

无论如何,希望至少澄清问题的那一部分.



7> rashedcs..:

在这里,我们可以定义用户定义的比较器:

代码如下:

 import java.util.*;
 import java.util.Collections;
 import java.util.Comparator; 


 class Checker implements Comparator
 {
    public int compare(String str1, String str2)
    {
        if (str1.length() < str2.length()) return -1;
        else                               return 1;
    }
 }


class Main
{  
   public static void main(String args[])
    {  
      PriorityQueue queue=new PriorityQueue(5, new Checker());  
      queue.add("india");  
      queue.add("bangladesh");  
      queue.add("pakistan");  

      while (queue.size() != 0)
      {
         System.out.printf("%s\n",queue.remove());
      }
   }  
}  

输出:

   india                                               
   pakistan                                         
   bangladesh

offer和add方法之间的区别:link

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有