试图覆盖 Java 中 PriorityQueue 的现有比较器

Posted

技术标签:

【中文标题】试图覆盖 Java 中 PriorityQueue 的现有比较器【英文标题】:Attempting to override existing comparator for PriorityQueue in Java 【发布时间】:2014-07-11 20:46:38 【问题描述】:

所以我正在尝试使用 java 中的优先级队列数据结构来实现 Dijkstra 算法。我唯一需要修改的是可比较运算符,因为 java 无法比较 Adjacency 类型的两个变量(用户定义)。我想使用 PriorityQueue 数据结构,我想做的就是修改 compareTo 运算符,以便它可以比较两个 Adjacency 类型的变量。截至目前,我得到的错误是“类型 PriorityQueue 必须实现继承的抽象方法 Comparable.compareTo(Adjacency)”。当我尝试在 compareTo 运算符上方添加“@override”标签时,我收到错误“无法将覆盖解析为类型”。

public class Adjacency 
  public int vertex;
  public double weight;
  public Adjacency(int v, double w) 
    vertex = v;
    weight = w;
  


public class PriorityQueue<T extends PriorityQueue<T>> implements Comparable<Adjacency> 


    public int compareTo(Adjacency o1, Adjacency o2) 
        return Double.compare(o1.weight, o2.weight);


    


编辑:这是实现 Comparator 的 Hello 类。我犯的错误是使用 Comparable 因为你只能比较这个和另一个变量,并且不能将两个单独的变量传递给类。实施 Comparator 解决了这个问题。

导入 java.util.*;

public class Hello implements Comparator<Adjacency>

    @Override
    public int compare(Adjacency o1, Adjacency o2) 
       return Double.compare(o1.weight, o2.weight);

      


【问题讨论】:

我有点困惑。您是在尝试实现自己的优先级队列还是使用 Java 的?如果您尝试使用 Java,则无需声明新的优先级队列类。您应该创建一个实现 Comparable 的新类,然后将其传递给 PriorityQueue 构造函数。 这个错误是因为你用两个参数指定了Comparable.compareTo,而该方法只有一个参数。 @Abrixas:没错,但这里真正的错误是 user2635911 混淆了ComparableComparator 【参考方案1】:

这不是你应该做的。不要子类化PriorityQueue。 最简单的方法是在 Ajacency 类中实现 Comparable&lt;Adjacency&gt;

在你的情况下,这可能是这样的:

public class Adjacency implements Comparable<Adjacency> 
    public int vertex;
    public double weight;
    public Adjacency(int v, double w) 
        vertex = v;
        weight = w;
    

    @Override
    public int compareTo(Adjacency other) 
        return Double.compare(this.weight, other.weight);
    

【讨论】:

这似乎有效,但不幸的是,我们不允许修改 Adjacency 类。我试图创建一个实现 Comparable 的新类(上面的代码在 EDIT 下)。我知道错误发生的原因,但不知道如何解决。 在这种情况下,另一个答案确实是更好的解决方案。【参考方案2】:

PriorityQueue 有一个构造函数that supports overriding its default Comparator

这意味着您必须为队列提供初始容量,但您还可以制作自己的自定义比较器,这是您想要的,而无需修改或触及 PriorityQueue 的实现.

除非您要求您的 Adjacency 类为 Comparable,否则您根本不需要在 Adjacency 上实现 Comparable

编辑:既然您已经让我们注意到您不能真正修改 Adjacency 类,那么使用自定义 Comparator 可能是正确的选择。

这是一个例子。您应该检查null;下面的 sn-p 仅用于说明目的。

Comparator<Adjacency> adjacencyComparator = new Comparator<Adjacency>() 

    @Override
    public int compare(Adjacency left, Adjacency right) 
        return left.weight.compareTo(right.weight);
     
;

【讨论】:

【参考方案3】:

您可以使用以下方法覆盖优先队列比较器:

    PriorityQueue<Adjacency>priorityQueue=new PriorityQueue<>(new Comparator<Adjacency>() 
        @Override
        public int compare(Adjacency adjacency, Adjacency t1) 
            return 0;
        
    );

只需根据需要更改比较样式...

【讨论】:

以上是关于试图覆盖 Java 中 PriorityQueue 的现有比较器的主要内容,如果未能解决你的问题,请参考以下文章

Java中PriorityQueue和TreeSet的区别? [复制]

java - 如何使用PriorityQueue集合从Java中的给定数组在O(n)时间内构建最大堆?

JAVA中priorityqueue详解

Scala PriorityQueue 冲突解决?

Python PriorityQueue 顺序

源码阅读(14):Java中主要的QueueDeque结构——PriorityQueue集合(下)