我如何使用PriorityQueue?

本文翻译自:How do I use a PriorityQueue?

How do I get a PriorityQueue to sort on what I want it to sort on? 如何让PriorityQueue对我希望它排序的内容进行排序?

Also, is there a difference between the offer and add methods? 另外, offeradd方法之间有区别吗?


#1楼

参考:https://stackoom.com/question/2rgn/我如何使用PriorityQueue


#2楼

Just to answer the add() vs offer() question (since the other one is perfectly answered imo, and this might not be): 只是回答add() vs offer()问题(因为另一个完全回答了imo,这可能不是):

According to JavaDoc on interface Queue , "The offer method inserts an element if possible, otherwise returning false. This differs from the Collection.add method, which can fail to add an element only by throwing an unchecked exception. The offer method is designed for use when failure is a normal, rather than exceptional occurrence, for example, in fixed-capacity (or "bounded") queues." 根据接口Queue上的JavaDoc ,“offer方法尽可能插入一个元素,否则返回false。这与Collection.add方法不同,Collection.add方法只能通过抛出未经检查的异常来添加元素.refer方法是为当故障是正常而非异常发生时使用,例如,在固定容量(或“有界”)队列中。“

That means if you can add the element (which should always be the case in a PriorityQueue), they work exactly the same. 这意味着如果你可以添加元素(在PriorityQueue中应该总是这样),它们的工作方式完全相同。 But if you can't add the element, offer() will give you a nice and pretty false return, while add() throws a nasty unchecked exception that you don't want in your code. 但是如果你不能添加元素, offer()将给你一个漂亮而漂亮的false返回,而add()会抛出你不想在代码中出现的令人讨厌的未经检查的异常。 If failure to add means code is working as intended and/or it is something you'll check normally, use offer() . 如果添加失败意味着代码按预期工作和/或它是您正常检查的内容,请使用offer() If failure to add means something is broken, use add() and handle the resulting exception thrown according to the Collection interface's specifications . 如果添加失败意味着某些内容被破坏,请使用add()并根据Collection接口的规范处理抛出的结果异常。

They are both implemented this way to fullfill the contract on the Queue interface that specifies offer() fails by returning a false ( method preferred in capacity-restricted queues ) and also maintain the contract on the Collection interface that specifies add() always fails by throwing an exception . 它们都是以这种方式实现的,以填充Queue接口上的合同,该接口通过返回false容量限制队列中首选的方法 offer()来指定offer()失败,并且还在Collection接口上维护合同, 指定add()始终失败抛出一个例外

Anyway, hope that clarifies at least that part of the question. 无论如何,希望至少澄清问题的那一部分。


#3楼

Java 8 solution Java 8解决方案

We can use lambda expression or method reference introduced in Java 8. In case we have some String values stored in the Priority Queue (having capacity 5) we can provide inline comparator (based on length of String) : 我们可以使用Java 8中引入的lambda expressionmethod reference 。如果我们在Priority Queue中存储了一些String值(容量为5),我们可以提供内联比较器(基于String的长度):

Using lambda expression 使用lambda表达式

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

Using Method reference 使用方法参考

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

Then we can use any of them as: 然后我们可以使用它们中的任何一个:

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

This will print: 这将打印:

Apple
PineApple
Custard Apple

To reverse the order (to change it to max-priority queue) simply change the order in inline comparator or use reversed as: 要反转顺序(将其改为最大优先级队列)简单地改变顺序以串联比较器或使用reversed为:

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

We can also use Collections.reverseOrder : 我们也可以使用Collections.reverseOrder

PriorityQueue<Integer> pqInt = new PriorityQueue<>(10, Collections.reverseOrder());
PriorityQueue<String> pq = new PriorityQueue<String>(5, 
                Collections.reverseOrder(Comparator.comparing(String::length))

So we can see that Collections.reverseOrder is overloaded to take comparator which can be useful for custom objects. 因此我们可以看到Collections.reverseOrder被重载以获取比较器,这对于自定义对象非常有用。 The reversed actually uses Collections.reverseOrder : reversed实际上使用Collections.reverseOrder

default Comparator<T> reversed() {
    return Collections.reverseOrder(this);
}

offer() vs add() offer()vs add()

As per the doc 根据文件

The offer method inserts an element if possible, otherwise returning false. 如果可能,offer方法插入一个元素,否则返回false。 This differs from the Collection.add method, which can fail to add an element only by throwing an unchecked exception. 这与Collection.add方法不同,后者只能通过抛出未经检查的异常来添加元素。 The offer method is designed for use when failure is a normal, rather than exceptional occurrence, for example, in fixed-capacity (or "bounded") queues. offer方法设计用于故障是正常而非异常发生时,例如,在固定容量(或“有界”)队列中。

When using a capacity-restricted queue, offer() is generally preferable to add(), which can fail to insert an element only by throwing an exception. 使用容量限制队列时,offer()通常优于add(),只能通过抛出异常来插入元素。 And PriorityQueue is an unbounded priority queue based on a priority heap. PriorityQueue是基于优先级堆的无界优先级队列。


#4楼

Priority Queue has some priority assigned to each element, The element with Highest priority appears at the Top Of Queue. 优先级队列为每个元素分配了一些优先级,具有最高优先级的元素出现在队列顶部。 Now, It depends on you how you want priority assigned to each of the elements. 现在,这取决于您希望如何为每个元素分配优先级。 If you don't, the Java will do it the default way. 如果不这样做,Java将以默认方式执行。 The element with the least value is assigned the highest priority and thus is removed from the queue first. 具有最小值的元素被赋予最高优先级,因此首先从队列中删除。 If there are several elements with the same highest priority, the tie is broken arbitrarily. 如果有多个元素具有相同的最高优先级,则可以任意打破平局。 You can also specify an ordering using Comparator in the constructor PriorityQueue(initialCapacity, comparator) 您还可以在构造函数 PriorityQueue(initialCapacity, comparator) 使用Comparator指定排序 PriorityQueue(initialCapacity, comparator)

Example Code: 示例代码:

PriorityQueue<String> queue1 = new PriorityQueue<>();
queue1.offer("Oklahoma");
queue1.offer("Indiana");
queue1.offer("Georgia");
queue1.offer("Texas");
System.out.println("Priority queue using Comparable:");
while (queue1.size() > 0) {
    System.out.print(queue1.remove() + " ");
}
PriorityQueue<String> queue2 = new PriorityQueue(4, Collections.reverseOrder());
queue2.offer("Oklahoma");
queue2.offer("Indiana");
queue2.offer("Georgia");
queue2.offer("Texas");
System.out.println("\nPriority queue using Comparator:");
while (queue2.size() > 0) {
    System.out.print(queue2.remove() + " ");
}

Output: 输出:

Priority queue using Comparable:
Georgia Indiana Oklahoma Texas 
Priority queue using Comparator:
Texas Oklahoma Indiana Georgia 

Else, You can also define Custom Comparator: 否则,您还可以定义自定义比较器:

import java.util.Comparator;

public class StringLengthComparator implements Comparator<String>
{
    @Override
    public int compare(String x, String y)
    {
        //Your Own Logic
    }
}

#5楼

In here, We can define user defined comparator: 在这里,我们可以定义用户定义的比较器:

Below code : 代码如下:

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


 class Checker implements Comparator<String>
 {
    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<String> queue=new PriorityQueue<String>(5, new Checker());  
      queue.add("india");  
      queue.add("bangladesh");  
      queue.add("pakistan");  

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

Output : 输出:

  india pakistan bangladesh 

Difference between the offer and add methods : link offer和add方法之间的区别: link


#6楼

no different, as declare in javadoc: 没有什么不同,如在javadoc中声明:

public boolean add(E e) {
    return offer(e);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值