2

TreeMapの実装を書いていますが、getメソッドとputメソッドで問題が発生しています。コードは次のとおりです。

public class MyTreeMap<K extends Comparable<? super K>,V> extends AbstractMap<K,V>  {


K key;
V value;
int height;
MyTreeMap<K,V> left,right;
int size;

private V get(K searchKey) {
    if(this.isEmpty())
        return null;//it needs an exception

    if(this.key.compareTo(searchKey) == 0)
        return this.value;
    else if(this.key.compareTo(searchKey) > 0)
        return this.left.get(searchKey);
    else
        return this.right.get(searchKey);
}

public V put(K key, V value) {

    if(this.containsKey(key)) {
        if(this.key.compareTo(key) == 0) {
            V temp = this.value;
            this.value = value;
            return temp;
        }

        else if(this.key.compareTo(key) < 0)
            return this.right.put(key, value);
        else if(this.key.compareTo(key) > 0)
            return this.left.put(key, value);
    }

    else {
        if(this.isLeaf() || this.isEmpty()) {
            if(this.key.compareTo(key) > 0) //this line gives NPE during tests
                this.left = new MyTreeMap(key,value,null,null);
            else
                this.right = new MyTreeMap(key,value,null,null);

               //check for balance and rebalance if needed
            this.size++;
            this.setHeight();
            return null;
        }

        else {
            if(this.key.compareTo(key) > 0)
                return this.left.put(key, value);
            else
                return this.right.put(key, value);
        }
    }
}

最もクレイジーなエラーは、putメソッドが別のreturnステートメントを必要とすることです。コードを何度もチェックすると、ブール式のステートメントが真である必要のないreturnステートメントがあるため、これは当てはまらないように思われます。

putメソッドをテストしているときに、NPEを取得します。何が悪いのか理解できないように見えるので、私のコードにはかなり重大な論理エラーがあると思います。これらのさまざまなエラーを修正するために正しい方向に私を向けていただければ、それは役に立ちます。ありがとうございました。

4

1 に答える 1

0

「余分な」returnステートメントについて:

if(this.containsKey(key)) {
    if(this.key.compareTo(key) == 0) {
        V temp = this.value;
        this.value = value;
        return temp;
    }

    else if(this.key.compareTo(key) < 0)
        return this.right.put(key, value);
    else if(this.key.compareTo(key) > 0)
        return this.left.put(key, value);
}

あなたの論理は、this.key.compareTo(key)に対してチェックしているので<0、すべてのケースがカバーされているということです。しかし、これはコンパイラーには当てはまりません。>0==0

  1. this.key.compareTo(key)コンパイラは、 の値が3 回の実行すべてで同じかどうかを知りません。メソッドをチェックし、他の入力を使用して結果を取得しないことを確認するインテリジェンスがあったとしても (そうではありません)、コンパイラーは、別のスレッドがキーの値を同時に変更しているかどうかを知る方法がありません。

  2. 実行しint value=this.key.compareTo(key)て後で に対してチェックを実行してもvalue、コンパイラは、連続する if-elsif が値のすべての範囲をカバーしていることをチェックしません。とにかく、パフォーマンス/並行性の理由から、このアプローチを使用してcompareTo1 回だけ呼び出すことをお勧めします。

最も簡単な修正は、最後else if (this.key.compareTo(key) > 0)を justに変更するelseことです (そのブロックが実行されるかどうかは、if が true でなければならないためであることを知っておく必要があります。

于 2012-11-02T08:56:41.200 に答える