[英]Create Custom Hashtable
我需要創建一個自定義哈希表擴展java.lang.Hashtable,並且我需要重寫get方法以實現以下行為:
誰能幫我。 我嘗試這樣做,但我知道這是錯誤的。
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();
}
知道錯誤發生在哪里。
您必須存儲與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
。
這里的主要問題是您試圖實現的目標基本上是錯誤的。 檢出類的方法。 現在大多數將與get
不一致。 更糟糕的是,未明確定義如何根據其他公共方法實現方法-繼承的詛咒。
因此,創建一個代表您要實現的抽象的類。 不要讓contain繼承自適當的地圖實現。
在這種情況下,自然映射可能不是舊的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
。)
為了創建,我假設了某種抽象工廠。 通常,方法沒有無參數的公共構造函數,它們不會拋出異常。 當然要避免像豬流感與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)
您需要創建一個新實例嗎? 還是返回默認實例就足夠了?
后者可以像這樣實現:
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;
}
}
(但我仍然更喜歡喬恩的工廠解決方案:更靈活,並且涵蓋了默認實例解決方案)
我了解您的要求,但請問以下內容:
我只是想知道您是否考慮過使用Apache Commons Collections中的LazyMap ?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.