2009-04-29 12 views
1

カスタムハッシュテーブルを作成し、私は次の動作を達成するためにgetメソッドをオーバーライドする必要があります。キーは== nullの場合、それが返された場合私は、カスタムのHashtableがjava.lang.Hashtable拡張作成する必要があり

  1. をsuper.get(キー)== nullの場合はタイプV
  2. の新しいオブジェクト、それはまた、誰も私を助けることができるタイプの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(v == null){ 
    return new Object(); 
} 

..

+0

何* *エラーですか?私は推測していますが、あなたは明白になりますか? –

+0

エラーは構文エラーです:メソッドの戻り値の型はVです。オブジェクト型を返そうとしています...これはエラーです – Saeed

答えて

10

あなたは、クラスを保存する必要があると思います:

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

や線を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を呼び出す:あなたのようなインタフェースでこれを行うと思います。

+0

反射を使用するように教えてください!!!!!!! eleventyone –

+0

Jon Skeetに感謝非常に... あなたの助けに感謝します.... ありがとうもう一度... – Saeed

0

私はあなたが尋ねたものを理解し、私は次のようにしてください頼むことができます:キーがnullのとき

  • あなたは常に新しいオブジェクトをしたいか、またはあなただけのヌルキーを許可したくないですか?
  • また、鍵を見つけることができないときには新しいインスタンスが必要ですか、鍵を見つけることができない場合も同じインスタンスが実行されますか?
  • 新しいインスタンスをHashtableに配置しますか?
  • ハッシュテーブルである必要がありますか、またはハッシュマップが行うことができますか?

Apache Commons CollectionsのLazyMapを使用したことがあると思っていますか?

+0

ありがとうA_M、LazyMapのアイデアも良いです、私は前にそれについて何も知らない。あなたの助けをありがとう – Saeed

2

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

+0

Carlos Heubergerありがとう あなたのアイデアも良いアイデアです... もう一度おねがいします... – Saeed

3

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の工場出荷時のソリューションを好みます)基本的に間違っている。あなたのクラスのメソッドをチェックアウトします。それらの大部分は今やgetと矛盾します。さらに悪いことに、メソッドが他のパブリックメソッドの観点からどのように実装されているかは定義されていません - 継承の呪いなどです。

したがって、達成しようとしている抽象を表すクラスを作成します。 にはが含まれていて、適切なマップの実装から継承されていません。

この場合の自然マップはおそらく古くはありませんHashtableしかしjava.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を使用することができます。)

を、私は抽象的な工場のいくつかの種類を想定してきました作成するには。一般的なメソッドでは、例外をスローしないような、引数を持たないpublicコンストラクタはありません。 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)

関連する問題