我想实现一个简单的Cache接口:
public interface Cache {
Object get(Object key);
Object put(Object key, Object value);
void clear();
}
我意识到它是java.util.Map接口的一部分。因此,像HashMap这样的对象应该能够传递给需要Cache对象的函数。
但另一方面,我不想让我自己的Cache类实现整个Map接口,因为我不需要除了这三个之外的其他方法。
Java不是一种鸭式语言,所以在这种情况下最好的做法是什么?
答案 0 :(得分:2)
我认为你可以在Cache
类
class CacheImpl<K, V> implements Cache<K, V> {
Map<K, V> cacheMap;
CacheImpl() {
this(new LinkedHashMap<>());
}
CacheImpl(Map<K,V> cacheMap) {
this.cacheMap = cacheMap;
}
@Override
public V get(K key) {
return cacheMap.get(key);
}
@Override
public V put(K key, V value) {
return cacheMap.put(key, value);
}
@Override
public void clear() {
cacheMap.clear();
}
}
我已经使用Generic添加了示例,但您可以随意使用Object作为键和值。
因此,在我的示例中,为了使其线程安全我们可以ConcurrentHashMap
已经thread safe
并且已经很好地实现了。我建议使用Factory类来创建缓存对象,如下所示。
class CacheImplFactory {
public static <K, V> Cache<K, V> newSimpleCache() {
return new CacheImpl<K, V>();
}
public static <K, V> Cache<K, V> newSynchronizedCache() {
return new CacheImpl<K, V>(new ConcurrentHashMap<>());
}
public static <K, V> Cache<K, V> newWeakCache() {
return new CacheImpl<K, V>(new WeakHashMap<>());
}
}
答案 1 :(得分:2)
java中没有这样的功能。
我认为你能做的最好的事情是在你担心的时候创建一个HashMap的包装器。
界面是合约。实现的类应该通过实现虚拟/抽象方法来填充合同。
您的CacheImpl
仅使用Cache
界面填写合同。同时HashMap
仅使用Map
界面填写合同。
具有相同签名的Cache
和Map
接口共享方法,但它们需要不同的合同/实现。
您实际上无法确定某个界面是否包含与您的Object put(Object key, Object value);
界面兼容的方法Cache
,因为您不了解该界面提供的合同。
所以在Java中,除非他们提供语义来创建现有界面的 &#34; parent&#34; 界面,否则你不能这样做。
答案 2 :(得分:1)
如果我理解你的问题,你就会问如何使用像HashMap这样的现有java类来支持接口。
您必须创建自己的实现来实现您的接口,并扩展HashMap。
Interface方法会将操作委托给HashMap。通过这种方式,您的自定义类将满足具有接口签名的任何Method的接口需求。
一个工作示例我聚集在一起展示如何做你在泛型中提出的问题:
缓存接口:
package interfaces;
public interface Cache<K,V> {
V get(K key);
V put(K key, V value);
void clear();
}
实施:
package classes;
import java.util.HashMap;
import interfaces.Cache;
public class MyCache<K,V> extends HashMap<K,V> implements Cache<K,V> {
private static final long serialVersionUID = 1L;
@Override
public V get(Object key) {
return super.get(key);
}
@Override
public V put(K key, V value) {
return super.put(key, value);
}
@Override
public void clear() {
super.clear();
}
}
然后您可以这样使用它:
import classes.MyCache;
import interfaces.Cache;
public class DoStuff {
private Cache<String,Integer> cache;
public void initCache() {
//This works
//Since MyCache implements Cache
MyCache<String,Integer> mCache=new MyCache<String,Integer>();
setCache(mCache);
//This will not
//Since HashMap does not implement Cache
HashMap<String,Integer> mMap=new HashMap<String,Integer>();
setCache(mMap);
}
public void setCache(Cache<String,Integer> c) {
cache=c;
}
public Cache<String,Integer> getCache() {
return cache;
}
}