简体   繁体   English

为什么我不能添加 PriorityQueue?

[英]Why can't I add on PriorityQueue?

I'm having troubles adding an Object Node to my PriorityQueue and I cant figure out why.我在将 Object 节点添加到我的 PriorityQueue 时遇到了麻烦,我不知道为什么。 When I add Node a, it has no problem.当我添加节点a时,它没有问题。

PriorityQueue<Node> q = new PriorityQueue<Node>();
Node a = new Node('a', 1);

q.add(a);

but if I add a second Node, it throws an exception saying "java.lang.ClassCastException: Node cannot be cast to java.lang.Comparable"但是如果我添加第二个节点,它会抛出一个异常说“java.lang.ClassCastException:节点不能转换为 java.lang.Comparable”

PriorityQueue<Node> q = new PriorityQueue<Node>();
Node a = new Node('a', 1);
Node b = new Node('b', 2);

q.add(a);
q.add(b);

My Node class is below:我的节点 class 如下:

public class Node {
    public int count;
    public char character;
    public Node left;
    public Node right;

    public Node(char character, int count) {
        this(character, count, null, null);
    }

    public Node(char character, int count, Node left, Node right) {
        this.count = count;
        this.character = character;
        this.left = left;
        this.right = right;
    }

    public int compareTo(Node other) {
        return this.count - other.count;
    }
}

I guess I'm just confused why it can add Node a but not add Node b.我想我只是很困惑为什么它可以添加节点 a 但不能添加节点 b。 I looked up what ClassCastException is and I dont really see that I did that kind of exception since I'm adding a type Node to a PriorityQueue of type Nodes.我查看了 ClassCastException 是什么,但我并没有真正看到我做了那种异常,因为我正在将类型 Node 添加到类型 Nodes 的 PriorityQueue 中。 I would appreciate any help.我将不胜感激任何帮助。 Thank you!谢谢!

The first one worked because it's the only one.第一个有效,因为它是唯一的。 From the second it needs to compare it against the first one to know where to place it on the priority queue.从第二个开始,它需要将其与第一个进行比较,以了解将其放置在优先级队列中的哪个位置。 You need to implement the interface Comparable on your Node class and implement the compare (a, b) method.您需要在节点 class 上实现接口 Comparable 并实现 compare (a, b) 方法。 Then the Priority queue will know how to properly order the items.然后优先队列将知道如何正确排序项目。

Node should inherit Comparable as follows: Node应该继承Comparable如下:

public class Node implements Comparable<Node> {
    ...

    @Override
    public int compareTo(Node n) {
        ...
    }
}

implements Comparable<Node> is missing in your class Node :在您的 class Node中缺少implements Comparable<Node>

public class Node implements Comparable<Node> {
    public int count;
    public char character;
    public Node left;
    public Node right;

    public Node(char character, int count) {
        this(character, count, null, null);
    }

    public Node(char character, int count, Node left, Node right) {
        this.count = count;
        this.character = character;
        this.left = left;
        this.right = right;
    }

    @Override
    public int compareTo(Node other) {
        return this.count - other.count;
    }
}

Either Node must implement Comparable (as some answers suggest), or a Comparator must be provided when creating the PriorityQueue - according javadoc要么Node必须实现Comparable (正如一些答案所暗示的那样),要么在创建PriorityQueue时必须提供Comparator - 根据javadoc

An unbounded priority queue based on a priority heap.基于优先级堆的无界优先级队列。 The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.优先级队列的元素根据它们的自然顺序进行排序,或者由队列构建时提供的Comparator排序,具体取决于使用的构造函数。 A priority queue does not permit null elements.优先级队列不允许 null 元素。 A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result in ClassCastException ).依赖于自然排序的优先级队列也不允许插入不可比较的对象(这样做可能会导致ClassCastException )。

From the documentation of PriorityQueue :PriorityQueue的文档中:

An unbounded priority queue based on a priority heap.基于优先级堆的无界优先级队列 The elements of the priority queue are ordered according to their natural ordering , or by a Comparator provided at queue construction time, depending on which constructor is used.优先级队列的元素根据其自然顺序或在队列构建时提供的Comparator进行排序,具体取决于使用的构造函数。 A priority queue does not permit null elements.优先级队列不允许null元素。 A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result in ClassCastException ).依赖于自然排序的优先级队列也不允许插入不可比较的对象(这样做可能会导致ClassCastException )。 [ emphasis added ] [强调补充]

The documentation of PriorityQueue#add(E) states it can throw: PriorityQueue#add(E)的文档说明它可以抛出:

ClassCastException - if the specified element cannot be compared with elements currently in this priority queue according to the priority queue's ordering ClassCastException - 如果指定的元素不能根据优先级队列的顺序与当前在此优先级队列中的元素进行比较

And you create your PriorityQueue using the no-argument constructor , whose documentation states:您使用无参数构造函数创建PriorityQueue ,其文档指出:

Creates a PriorityQueue with the default initial capacity ( 11 ) that orders its elements according to their natural ordering .创建一个具有默认初始容量 ( 11 ) 的PriorityQueue ,它根据元素的自然顺序对其元素进行排序

For an object to have a natural ordering it must implement the Comparable interface.为了使 object 具有自然排序,它必须实现Comparable接口。 Since your Node class does not implement Comparable you get a ClassCastException when adding the second element (due to there now being enough elements to start comparing them).由于您的Node class 没有实现Comparable ,因此在添加第二个元素时会收到ClassCastException (因为现在有足够的元素来开始比较它们)。 There are at least two solutions:至少有两种解决方案:

  1. Have Node implement Comparable<Node> :Node实现Comparable<Node>

     public class Node implements Comparable<Node> { // fields and other methods omitted for brevity @Override // annotation forces compiler to check if method actually overrides anything public int compareTo(Node other) { // compare 'this' and 'other' based on their properties and return result... } }
  2. Pass a Comparator implementation when creating the PriorityQueue :创建PriorityQueue时传递Comparator实现:

     PriorityQueue<Node> queue = new PriorityQueue<>((left, right) -> /* compare */);

Also see Java: Comparable vs Comparator [duplicate] .另请参阅Java:Comparable vs Comparator [duplicate]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM