我有一系列各种不相关的接口,每个接口都有一个实现。我想将这些键值对存储在地图中:
Class<Person>, Class<Student>
Class<Animal>, Class<Lion>
...
映射应该只允许满足该值是键的实现的条目(或者至少key.isAssignableFrom(value)
为真)。直观地说,我想将地图定义为类的字段:
private Map<Class<? as T>, Class<? extends T>> myMap;
但是当然这不是有效的Java 8语法。
如何制作此类地图?
下面的设计似乎有用( - 忽略性能和并发问题),但我更喜欢更简单的解决方案。
public static class MapHolder {
private final HashMap<Class<?>, Class<?>> privateMap = new HashMap<>();
public <K, V extends K> Class<V> get(Class<K> key){
return (Class<V>) privateMap.get(key);
}
public <K, V extends K> Class<V> put(Class<K> key, Class<V> value){
return (Class<V>) privateMap.put(key, value);
}
public <K, V extends K> Set<Entry<Class<K>, Class<V>>> entrySet() {
Set<Entry<Class<K>, Class<V>>> list = new HashSet<>();
for (Class<?> clazz : privateMap.keySet()) {
list.add(new AbstractMap.SimpleEntry(clazz, privateMap.get(clazz)));
}
return list;
}
}
调用者可能会对将条目添加为某些依赖注入框架的绑定感兴趣。但是上面的代码强制调用者创建一个参数化方法,以便他/她利用键和值之间的接口 - 实现关系。至少这是我开始工作的方式:
public static <K, V extends K> void traverse(MapHolder m){
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure() {
Set<Entry<Class<K>,Class<V>>> set = m.entrySet();
for (Entry<Class<K>,Class<V>> entry : set){
this.bind(entry.getKey()).to(entry.getValue());
}
}
});
}