Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java中的泛型实现堆_Java_Arrays_Generics_Heap_Comparable - Fatal编程技术网

用Java中的泛型实现堆

用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

我想实现一个基于数组的堆。但是,此堆应该可以使用一个数组调用,该数组只能包含实现可比较接口的元素,也可以包含一个额外的比较器(因此,如果没有提供比较器,则假定每个元素都可以相互比较)。然后我想检查一下它的有效性。它不起作用,因为无法调用extends Comparable的heapCondition

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;
}