Java 在不可比较对象上使用优先级队列,其中包含可比较对象
我正在为一个类构建一个哈夫曼树。在检查了可用选项后,我决定使用优先级队列方法。然而,当我尝试运行下面的代码时,我在TreeNode上得到了ClassCastException(在第一行pq.offer上)Java 在不可比较对象上使用优先级队列,其中包含可比较对象,java,priority-queue,comparable,huffman-code,Java,Priority Queue,Comparable,Huffman Code,我正在为一个类构建一个哈夫曼树。在检查了可用选项后,我决定使用优先级队列方法。然而,当我尝试运行下面的代码时,我在TreeNode上得到了ClassCastException(在第一行pq.offer上) 公共静态树节点构建树(ArrayList树)引发IOException{ PriorityQueue pq=新的PriorityQueue(); 对于(int i=0;i0){ 提供(新的TreeNode(新的CharFreq(trees.get(i).getItem().getChar(),
公共静态树节点构建树(ArrayList树)引发IOException{
PriorityQueue pq=新的PriorityQueue();
对于(int i=0;i0){
提供(新的TreeNode(新的CharFreq(trees.get(i).getItem().getChar(),trees.get(i).getItem().getFreq()));
}
}
而(pq.size()>1){
TreeNode leftNode=pq.poll();
TreeNode rightNode=pq.poll();
TreeNode parentNode=新的TreeNode(新的CharFreq('\u0000',((leftNode.getItem().getFreq())+(rightNode.getItem().getFreq())),leftNode,rightNode);
}
返回pq.poll();
}
我知道它不是一个可比较的类,然而,CharFreq是,我的问题是我是否能够修复我的代码以避免这个铸造问题 优先级队列使用
比较器
(在构造函数中提供),或者直接将对象强制转换为可比
为了避免ClassCastException,您应该提供一个TreeNode
的Comparator
。这样队列将使用比较器而不是强制转换
PriorityQueue<TreeNode<CharFreq>> pq = new PriorityQueue<TreeNode<CharFreq>>(initialCapacity, comparator);
PriorityQueue pq=新的PriorityQueue(初始容量,比较器);
您可以创建自定义比较器:比较器
并在创建PriorityQueue时使用它:
,java.util.Comparator)
创建具有指定初始容量的PriorityQueue,该队列根据指定的比较器对其元素进行排序
使用该概念,您可以得到如下代码:
public static TreeNode<CharFreq> buildTree(ArrayList<TreeNode<CharFreq>> trees)
throws IOException {
Comparator<TreeNode<CharFreq>> comparator = new Comparator<TreeNode<CharFreq>>() {
//basic implementation, you must use your own!
public int compare(TreeNode<CharFreq> node1, TreeNode<CharFreq> node2) {
return node1.data.compareTo(node2.data);
}
};
PriorityQueue<TreeNode<CharFreq>> pq = new PriorityQueue<TreeNode<CharFreq>>(10, comparator);
//the rest of your code...
}
公共静态树节点构建树(ArrayList树)
抛出IOException{
比较器比较器=新比较器(){
//基本实现,您必须使用自己的!
公共整数比较(树节点1、树节点2){
返回node1.data.compareTo(node2.data);
}
};
PriorityQueue pq=新的PriorityQueue(10,比较器);
//剩下的代码。。。
}
请注意,使用这种方式意味着每次需要创建
PriorityQueue
时都必须创建自定义的比较器。创建比较器的问题是,由于赋值限制,我无法更改TreeNode类@Darkstarone您不需要修改TreeNode
类来创建比较器。请看我的答案,看看一个基本的实现。代替“node1.compareTo(node2)”;“您应该有”node1.getCharFreq().compareTo(node2.getCharFreq());“但这是假设您在树节点中有getCharFreq()方法。您可能有一些更通用的工具,比如getContent(),但需要能够访问TreeNode中的内部元素,否则您必须重新编写TreeNode才能进行比较。@Lauri right,答案已编辑。顺便说一句,OP没有显示数据是如何存储在它的TreeNode
类中的,我假设它可能是data
属性或类似的属性。好吧,构建了比较器,但是,我不确定如何实现它。我得到了:PriorityQueue pq=new PriorityQueue(trees.size(),comparator),但这对我在静态上下文中引用非静态比较器大喊大叫。@Darkstarone你在方法内部创建了比较器了吗?我编辑了我的答案,告诉你怎么做。啊,非常感谢。现在变得更有意义了。今晚首先进入优先队列。谢谢你让它变得简单!若您有权访问TreeNode代码,可以向其中添加compareTo()方法并实现Comparable接口。这对你们想做的工作来说可能更容易。在这种情况下,您的TreeNode包含的元素应该始终是可比较的。为了提供更好的答案,最好看看TreeNode类的实现。您可以编辑此问题并将其添加到此处。
public static TreeNode<CharFreq> buildTree(ArrayList<TreeNode<CharFreq>> trees)
throws IOException {
Comparator<TreeNode<CharFreq>> comparator = new Comparator<TreeNode<CharFreq>>() {
//basic implementation, you must use your own!
public int compare(TreeNode<CharFreq> node1, TreeNode<CharFreq> node2) {
return node1.data.compareTo(node2.data);
}
};
PriorityQueue<TreeNode<CharFreq>> pq = new PriorityQueue<TreeNode<CharFreq>>(10, comparator);
//the rest of your code...
}