带有自定义匿名比较器的Java优先级队列

带有自定义匿名比较器的Java优先级队列,java,priority-queue,Java,Priority Queue,请原谅我,如果这是一个久经考验的问题,但我有点难以理解 我现在有一个类节点,每个节点都是迷宫中的一个正方形。我正在尝试实现A*算法,因此每个节点都有一个f-cost(int)数据成员。我想知道是否有一种方法可以创建这些节点的优先级队列,并将f-cost变量设置为比较器 我在网上看过一些例子,但我能找到的只是字符串优先级队列。我可以为节点类实现比较器吗?这是否允许我访问存储在其中的数据成员 非常感谢 来自Javadocs: 基于 优先级堆。这个队列命令 按顺序排列的元素 在施工时指定,其中 是根据

请原谅我,如果这是一个久经考验的问题,但我有点难以理解

我现在有一个类节点,每个节点都是迷宫中的一个正方形。我正在尝试实现A*算法,因此每个节点都有一个f-cost(int)数据成员。我想知道是否有一种方法可以创建这些节点的优先级队列,并将f-cost变量设置为比较器

我在网上看过一些例子,但我能找到的只是字符串优先级队列。我可以为节点类实现比较器吗?这是否允许我访问存储在其中的数据成员

非常感谢

来自Javadocs:

基于 优先级堆。这个队列命令 按顺序排列的元素 在施工时指定,其中 是根据其 自然顺序(见可比),或 根据比较法

此外,PriorityQueues支持通用数据类型。因此,如果在节点类中实现了
Comparable
,则可以创建
PriorityQueue
并正常使用它


或者,有一个构造函数
PriorityQueue(int initialCapacity,Comparatorjava.util中有一个PriorityQueue类。您可以使用它,它将使用自然排序(节点实现可比较)或构造函数中提供的比较器(如果您不想在节点类中使用该代码)。任何类都可以访问另一个类中的任何数据,只要您允许,可以通过将字段设置为非私有(可能是糟糕的OOP样式)或提供访问器方法public int getG()、public int getH()、public int getF()。

您可以使用基于传递给构造函数的匿名比较器的
PriorityQueue

int initCapacity = 10;
PriorityQueue<Node> pq = new PriorityQueue<Node>(initCapacity, new Comparator<Node>() {
    public int compare(Node n1, Node n2) {
        // compare n1 and n2
    }
});
// use pq as you would use any PriorityQueue
int initCapacity=10;
PriorityQueue pq=新的PriorityQueue(初始容量,新比较器(){
公共整数比较(节点n1、节点n2){
//比较n1和n2
}
});
//使用pq就像使用任何PriorityQueue一样
如果您的
节点
类已经实现了
可比
,您甚至不需要定义新的
比较器
,因为默认情况下将使用该顺序。除非使用任何其他方法,否则将使用对象之间的自然顺序。

公共类节点实现可比{
public class Node implements Comparable<Node>{

    public int compareTo(Node o) {
         // your comparative function
         return 0;
    }
公共整数比较(节点o){ //你的比较功能 返回0; }
}

如果compareTo返回负整数,则表示“小于”,0表示“等于”,1表示“大于”

使用PriorityQueue只需要一个函数


编辑:比较是另一种方式,我把它搞砸了。-1出于某种原因,我总是从右到左阅读这些内容。

这个问题不久前就得到了回答,我想给出一些可用的新选项

1) 如果您的
节点
类未实现Comparator接口且您不想(或不能)添加它,则使用lambda:

newpriorityqueue((node1,node2)->Integer.compare(node1.getCost(),node2.getCost());
2) 简单的逆序方法(要求节点实现比较器接口):

newpriorityqueue(Comparator.reverseOrder());
3) 使用效用函数:

  new PriorityQueue<>(NodeUtil::customCompare);

  public static int customCompare(Node n1, Node n2) {
       return Integer.compare(n1.getCost(), n2.getCost());
  }
newpriorityqueue(NodeUtil::customCompare);
公共静态int customCompare(节点n1、节点n2){
返回整数.compare(n1.getCost(),n2.getCost());
}

谢谢!看来我只是有点难搞清楚超控位,你说得很清楚!你好@YuvalAdam你能举一个使用lambda比较器的PriorityQueue的例子吗?谢谢!除了比较位外,我几乎走上了正轨,+ve,-ve清楚地表明了这一点。爱入侵者Zim阿凡达顺便说一句,小心,比较结果是“向后的”:排名较低的值首先返回。如果你认为优先级队列是按升序排序的列表,这是有道理的,但它混淆了我第一次使用的一个地狱,正如我所预期的,优先级为100的元素明显比优先级30的元素更明显。
  new PriorityQueue<>(Comparator.reverseOrder());
  new PriorityQueue<>(NodeUtil::customCompare);

  public static int customCompare(Node n1, Node n2) {
       return Integer.compare(n1.getCost(), n2.getCost());
  }