我需要创建一个Custom Hashtable extends 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();
}
知道错误发生的位置..
答案 0 :(得分: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
。
答案 1 :(得分:3)
这里的主要问题是你想要实现的根本是错误的。查看班级的方法。其中大部分现在与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
。)
创造我假设某种抽象工厂。通常,方法没有no-args公共构造函数,它们不会抛出异常。当然要避免像猪流感与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)
答案 2 :(得分: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的工厂解决方案:更灵活,也涵盖默认的实例解决方案)
答案 3 :(得分:0)
我理解你的要求,但我可以问下面的事情:
我只是想知道您是否考虑过使用Apache Commons Collections中的LazyMap?