1

カスタムハッシュテーブルextendsjava.lang.Hashtableを作成する必要があり、次の動作を実現するためにgetメソッドをオーバーライドする必要があります。

  1. key == nullの場合、タイプVの新しいオブジェクトを返します
  2. super.get(key)== nullの場合、タイプVの新しいオブジェクトも返します。

誰かが私を助けることができますか?私はこれをやろうとしますが、それが間違っていることを知っています。

import java.util.Hashtable;

public class CustomHashtable<K, V> extends Hashtable {
    @Override
    public synchronized V get(Object key) {
        if(key == null) return new Object();
        Object v = super.get(key);
        if(v == null){
            return new Object();
        }
    }

}

次の行を参照してください:

if(key == null) return new Object();

と行:

if(v == null){
    return new Object();
}

エラーが発生した場所を知るために。

4

4 に答える 4

10

V に関連するクラスを保存し、新しいインスタンスを作成する必要があります。例えば:

public class CustomHashtable<K, V> extends Hashtable {
    Class<V> clazz;

    public CustomHashtable(Class<V> clazz) {
        this.clazz = clazz;
    }

    @Override
    public synchronized V get(Object key) {
        if(key == null) return newValue();
        Object v = super.get(key);
        if(v == null){
            return newValue();
        }
    }

    private V newValue() {
        try {
            return clazz.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException (e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException (e);
        }
    }
}

(もちろん、例外処理を変更することもできます。)

別の方法として、呼び出し元に の新しいインスタンスを作成するためのファクトリを効果的に提供させることもできますV。次のようなインターフェースでこれを行います。

public interface Factory<T> {
    T create();
}

その後、ファクトリをカスタム ハッシュテーブルに格納し、create必要なときにいつでも呼び出すことができます。

于 2009-04-29T09:05:49.927 に答える
3

ここでの主な問題は、あなたが達成しようとしていることが根本的に間違っているということです。クラスのメソッドをチェックアウトします。それらの大部分は現在、 と矛盾していgetます。さらに悪いことに、メソッドが他のパブリック メソッドに関してどのように実装されるかは正確には定義されていません。これが継承の呪いです。

したがって、達成しようとしている抽象化を表すクラスを作成します。適切なマップの実装から継承しないでください

この場合の自然な地図はおそらく古いものではありませHashtablejava.util.concurrent.ConcurrentHashMap。ここで重要なメソッドは [ putIfAbsent][2] です。残念ながら、API ドキュメントは最悪です。使用方法は次のとおりです。

public V getOrCreate(K key) {
    final V value = map.get(key);
    if (value != null) {
        return value;
    }
    V newValue = factory.create(key); // May discard.
    V oldValue = map.putIfAbsent(key, value);
    return oldValue==null ? newValue : oldValue;
}

(Future値を破棄しないようにする場合は、 a を使用できます。)

作成するために、私はある種の抽象工場を想定しました。一般に、メソッドには、たまたま例外をスローしない引数なし​​のパブリック コンストラクターがありません。H5N1 と交配した豚インフルエンザのような反射は絶対に避けてください。代わりに、作成時に渡された適切な (抽象化固有の) 抽象ファクトリを使用します。

public interface MySortOfFactory<
    T /*extends SomeEntity*/,
    A /*extends SomeInfo*/
> {
    T create(A arg);
}

[2]: http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentMap.html#putIfAbsent(K , V)

于 2009-04-29T11:21:12.503 に答える
2

新しいインスタンスを作成する必要がありますか? または、デフォルトのインスタンスを返すだけで十分ですか?
後者は次のように実装できます。

public class CustomHashtable<K, V> extends Hashtable<K, V> {

    /** Default instance. */
    private final V defaultValue;

    public CustomHashtable(V defaultValue) {
        this.defaultValue= defaultValue;
    }

    @Override
    public synchronized V get(Object key) {
        if(key != null) {
            V val = super.get(key);
            if(val != null) {
                return val;
            }
        }
        return defaultValue;
    }
}

(しかし、私はまだ Jon のファクトリ ソリューションを好みます。より柔軟で、デフォルトのインスタンス ソリューションもカバーしています)

于 2009-04-29T09:47:15.617 に答える
0

ご質問の内容は理解できましたが、次のことをお願いできますでしょうか。

  • キーが null の場合は常に新しいオブジェクトが必要ですか、それとも null キーを許可したくないだけですか?
  • また、キーが見つからない場合は必ず新しいインスタンスが必要ですか、それともキーが見つからない場合でも同じインスタンスが必要ですか?
  • 新しいインスタンスを Hashtable に入れますか?
  • Hashtable である必要がありますか、それとも HashMap でよいでしょうか?

Apache Commons CollectionsのLazyMapを使用することを検討したかどうか疑問に思っていますか?

于 2009-04-29T09:39:11.907 に答える