用Java中的泛型实现堆
我想实现一个基于数组的堆。但是,此堆应该可以使用一个数组调用,该数组只能包含实现可比较接口的元素,也可以包含一个额外的比较器(因此,如果没有提供比较器,则假定每个元素都可以相互比较)。然后我想检查一下它的有效性。它不起作用,因为无法调用extends Comparable的heapCondition用Java中的泛型实现堆,java,arrays,generics,heap,comparable,Java,Arrays,Generics,Heap,Comparable,我想实现一个基于数组的堆。但是,此堆应该可以使用一个数组调用,该数组只能包含实现可比较接口的元素,也可以包含一个额外的比较器(因此,如果没有提供比较器,则假定每个元素都可以相互比较)。然后我想检查一下它的有效性。它不起作用,因为无法调用extends Comparable的heapCondition public class Heap <T>{ Object[] tree; Comparator<T> comparator; public <T extends C
public class Heap <T>{
Object[] tree;
Comparator<T> comparator;
public <T extends Comparable<T>> Heap(T[] tree){
this.tree = tree;
}
public Heap(T[] tree, Comparator<T> comparator){
this.tree = tree;
this.comparator = comparator;
}
/**
* defines the heapCondition default is set so the Heap is a minHeap (parent is smaller than their children)
* @param parent parent node
* @param child child node
*/
public <T extends Comparable<T>> boolean heapCondition(T parent, T child){
return parent.compareTo(child) < 0;
}
public boolean heapCondition(T parent, T child){
if(comparator == null){
// go into the heap condition where to Comparable is assumed
heapCondition(parent,child);
}
return comparator.compare(parent,child) < 0;
}
/**
* @return boolean whether or not the current tree fulfills the Heap condition
*
*/
private boolean valid(){
for(int i = 0; 2*i+2 < tree.length; i++){
// returns false if the condition is not met for one of the children
return !(!heapCondition((T) tree[i], (T) tree[2*i+1]) || !heapCondition((T) tree[i],(T) tree[2*i+2]));
}
return true;
}
}
公共类堆{
对象[]树;
比较器;
公共堆(T[]树){
this.tree=树;
}
公共堆(T[]树,比较器){
this.tree=树;
这个比较器=比较器;
}
/**
*定义heapCondition默认设置,使堆为minHeap(父堆小于其子堆)
*@param父节点
*@param子节点
*/
公共布尔heapCondition(T父级,T子级){
返回parent.compareTo(child)<0;
}
公共布尔heapCondition(T父级,T子级){
if(比较器==null){
//进入假设可比较的堆条件
健康状况(父母、子女);
}
返回比较器。比较(父级、子级)<0;
}
/**
*@return boolean当前树是否满足堆条件
*
*/
私有布尔有效(){
对于(int i=0;2*i+2
在您的实现中,堆
和公共布尔堆条件
是不同的T
s。泛型方法从类定义创建其他T
和阴影T
。这就是为什么public boolean heapCondition
无法调用public boolean heapCondition
实际上,如果Comparator==null
和t
为任何类,则不能要求t
为Comparable
java.util.TreeMap
实现了类似的功能。当Comparator==null
时,它使用compareTo
。但是,当对象不可比较时,可以使用运行时强制转换和抛出ClassCastException
,来完成此逻辑。下面是java.util.TreeMap的JavaDoc
/**
* Constructs a new, empty tree map, using the natural ordering of its
* keys. All keys inserted into the map must implement the {@link
* Comparable} interface. Furthermore, all such keys must be
* <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
* a {@code ClassCastException} for any keys {@code k1} and
* {@code k2} in the map. If the user attempts to put a key into the
* map that violates this constraint (for example, the user attempts to
* put a string key into a map whose keys are integers), the
* {@code put(Object key, Object value)} call will throw a
* {@code ClassCastException}.
*/
public TreeMap() {
comparator = null;
}
解决方案
您需要删除除Heap
definition之外的所有泛型。另外,当您的比较器==null
时,您不会返回结果,因此会进行无限递归。在valid
方法中,您总是在第一次迭代之后返回
下面是您的堆的外观
class Heap<T> {
T[] tree;
Comparator<? super T> comparator;
public Heap(T[] tree) {
this.tree = tree;
this.comparator = null;
}
public Heap(T[] tree, Comparator<? super T> comparator) {
this.tree = tree;
this.comparator = comparator;
}
/**
* defines the heapCondition default is set so the Heap is a minHeap (parent is smaller than their children)
*
* @param parent parent node
* @param child child node
*/
public boolean heapConditionComparable(T parent, T child) {
@SuppressWarnings("unchecked")
Comparable<? super T> comparableParent = (Comparable<? super T>) parent;
return comparableParent.compareTo(child) < 0;
}
public boolean heapCondition(T parent, T child) {
if (comparator == null) {
// go into the heap condition where to Comparable is assumed
return heapConditionComparable(parent, child);
}
return comparator.compare(parent, child) < 0;
}
/**
* @return boolean whether or not the current tree fulfills the Heap condition
*/
boolean valid() {
for (int i = 0; i < (tree.length - 2) / 2; ++i) {
// returns false if the condition is not met for one of the children
if (!(!heapCondition(tree[i], tree[2 * i + 1]) || !heapCondition(tree[i], tree[2 * i + 2]))) {
return false;
}
}
return true;
}
}
类堆{
T[]树;
在您的实现中,Comparator与public boolean heapCondition
不是相同的T
s。通用方法从类定义创建其他T
和阴影T
。这就是public boolean heapCondition
无法调用public boolean heapCondition
实际上,当Comparator==null
和t
为任何类时,不能要求t
为Comparator
,否则t
为任何类。java.util.TreeMap
实现类似的功能。当Comparator==null
时,它使用compareTo
。但这个逻辑是通过使用运行时强制转换来完成的当对象不可比较时抛出ClassCastException
/**
* Constructs a new, empty tree map, using the natural ordering of its
* keys. All keys inserted into the map must implement the {@link
* Comparable} interface. Furthermore, all such keys must be
* <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
* a {@code ClassCastException} for any keys {@code k1} and
* {@code k2} in the map. If the user attempts to put a key into the
* map that violates this constraint (for example, the user attempts to
* put a string key into a map whose keys are integers), the
* {@code put(Object key, Object value)} call will throw a
* {@code ClassCastException}.
*/
public TreeMap() {
comparator = null;
}
解决方案
您需要删除除堆
定义之外的所有泛型。此外,当比较器==null
时,您不会返回结果,从而进行无限递归。在有效的
方法中,您总是在第一次迭代后返回
下面是您的堆的外观
class Heap<T> {
T[] tree;
Comparator<? super T> comparator;
public Heap(T[] tree) {
this.tree = tree;
this.comparator = null;
}
public Heap(T[] tree, Comparator<? super T> comparator) {
this.tree = tree;
this.comparator = comparator;
}
/**
* defines the heapCondition default is set so the Heap is a minHeap (parent is smaller than their children)
*
* @param parent parent node
* @param child child node
*/
public boolean heapConditionComparable(T parent, T child) {
@SuppressWarnings("unchecked")
Comparable<? super T> comparableParent = (Comparable<? super T>) parent;
return comparableParent.compareTo(child) < 0;
}
public boolean heapCondition(T parent, T child) {
if (comparator == null) {
// go into the heap condition where to Comparable is assumed
return heapConditionComparable(parent, child);
}
return comparator.compare(parent, child) < 0;
}
/**
* @return boolean whether or not the current tree fulfills the Heap condition
*/
boolean valid() {
for (int i = 0; i < (tree.length - 2) / 2; ++i) {
// returns false if the condition is not met for one of the children
if (!(!heapCondition(tree[i], tree[2 * i + 1]) || !heapCondition(tree[i], tree[2 * i + 2]))) {
return false;
}
}
return true;
}
}
类堆{
T[]树;
Comparator您可以查看处理类似问题的TreeMap
,但我觉得它的方法不是很优雅。我会使用静态工厂方法进行更好的类型控制,并为自然排序指定默认比较器。这样,您就不必担心调用哪个比较方法:
public static <T> Heap<T> create(T[] tree, Comparator<T> comparator) {
return new Heap<>(tree, comparator);
}
public static <T extends Comparable<T>> Heap<T> create(T[] tree) {
return new Heap<>(tree, Comparator.naturalOrder());
}
private Heap(T[] tree, Comparator<T> comparator) {
this.tree = tree;
this.comparator = comparator;
}
public boolean heapCondition(T parent, T child) {
return comparator.compare(parent, child) < 0;
}
公共静态堆创建(T[]树,比较器){
返回新堆(树、比较器);
}
公共静态堆创建(T[]树){
返回新堆(tree,Comparator.naturalOrder());
}
私有堆(T[]树,比较器){
this.tree=树;
这个比较器=比较器;
}
公共布尔heapCondition(T父级,T子级){
返回比较器。比较(父级、子级)<0;
}
您可以查看处理类似问题的TreeMap
,但我觉得它的方法并不优雅。我会使用静态工厂方法来实现更好的类型控制,并为自然排序指定默认比较器。这样,您就不必担心调用哪个比较方法:
public static <T> Heap<T> create(T[] tree, Comparator<T> comparator) {
return new Heap<>(tree, comparator);
}
public static <T extends Comparable<T>> Heap<T> create(T[] tree) {
return new Heap<>(tree, Comparator.naturalOrder());
}
private Heap(T[] tree, Comparator<T> comparator) {
this.tree = tree;
this.comparator = comparator;
}
public boolean heapCondition(T parent, T child) {
return comparator.compare(parent, child) < 0;
}
公共静态堆创建(T[]树,比较器){
返回新堆(树、比较器);
}
公共静态堆创建(T[]树){
返回新堆(tree,Comparator.naturalOrder());
}
私有堆(T[]树,比较器){
this.tree=树;
这个比较器=比较器;
}
公共布尔heapCondition(T父级,T子级){
返回比较器。比较(父级、子级)<0;
}