我想找到或实现与Guava中的MutableGuiceKeyToInstanceMap
相似的com.google.common.collect.MutableClassToInstanceMap
,但是要使用Guice中的com.google.inject.Key<T>
代替Class<T>
。
我无法在Guice中找到它,也无法以MutableClassToInstanceMap
的实现方式实现它,因为它的超类ConstrainedMap
是程序包私有的。我也不能使用MapConstraint.constrainedMap
,因为我没有机会添加方法getInstance
和putInstance
(没有它们,它们将毫无意义)。
自己复制ConstrainedMap
类的副本将迫使我复制很多其他的类,因此这不是可行的方法。通过MapConstraint.constrainedMap
制作一个辅助地图并制作将所有内容委派给该助手的MutableGuiceKeyToInstanceMap extends ForwardingMap
都可以,但是仍然很麻烦。有更好的主意吗?
您认为提议公开ConstrainedMap
是个好主意吗?
最佳答案
我不明白您为什么不喜欢ForwardingMap
和MapConstraint.constrainedMap
的组合。该代码非常简单,并且看起来几乎完全与直接扩展ConstrainedMap
时的结果类似:
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.MapConstraint;
import com.google.common.collect.MapConstraints;
import com.google.inject.Key;
import org.apache.commons.lang.NotImplementedException;
import java.util.HashMap;
import java.util.Map;
public final class MutableGuiceKeyToInstanceMap<B>
extends ForwardingMap<Key<? extends B>, B> {
/**
* Returns a new {@code MutableGuiceKeyToInstanceMap} instance backed by a {@link
* java.util.HashMap} using the default initial capacity and load factor.
*/
public static <B> MutableGuiceKeyToInstanceMap<B> create() {
return new MutableGuiceKeyToInstanceMap<B>(new HashMap<Key<? extends B>, B>());
}
/**
* Returns a new {@code MutableGuiceKeyToInstanceMap} instance backed by a given
* empty {@code backingMap}. The caller surrenders control of the backing map,
* and thus should not allow any direct references to it to remain accessible.
*/
public static <B> MutableGuiceKeyToInstanceMap<B> create(Map<Key<? extends B>, B> backingMap) {
return new MutableGuiceKeyToInstanceMap<B>(backingMap);
}
private final Map<Key<? extends B>, B> delegate;
private MutableGuiceKeyToInstanceMap(Map<Key<? extends B>, B> delegate) {
this.delegate = MapConstraints.constrainedMap(delegate, VALUE_MATCHES_GUICE_KEY);
}
@Override
protected Map<Key<? extends B>, B> delegate() {
return delegate;
}
private static final MapConstraint<Key<?>, Object> VALUE_MATCHES_GUICE_KEY = new MapConstraint<Key<?>, Object>() {
@Override
public void checkKeyValue(Key<?> key, Object value) {
matchesGuiceKey(key, value);
}
};
public <T extends B> T putInstance(Key<T> key, T value) {
return matchesGuiceKey(key, put(key, value));
}
public <T extends B> T getInstance(Key<T> key) {
return matchesGuiceKey(key, get(key));
}
private static <B, T extends B> T matchesGuiceKey(Key<T> key, B value) {
throw new NotImplementedException("TODO");
}
private static final long serialVersionUID = 0;
}
该代码与
MutableClassToInstanceMap
非常相似,并且无需扩展ForwardingMap
...当然,您需要添加delegate()
方法及其随附字段,但其余部分相同。我省略了
matchesGuiceKey()
实现作为读者的练习。祝好运!您might need it。