创建MutableGuiceKeyToInstanceMap最简单的方法?

时间:2011-05-09 18:35:31

标签: java map guice guava

我想找到或实施MutableGuiceKeyToInstanceMap,就像来自Guava的com.google.common.collect.MutableClassToInstanceMap一样,但是使用来自Guice的com.google.inject.Key<T>代替Class<T>

我在Guice中找不到它,我无法按照MutableClassToInstanceMap的实现方式实现它,因为它的超类ConstrainedMap是包私有的。我也不能使用MapConstraint.constrainedMap,因为我没有机会添加方法getInstanceputInstance(没有它们,这一切都毫无意义)。

制作ConstrainedMap类的自己的副本会迫使我复制其他几个类,所以这不是可行的方法。通过MapConstraint.constrainedMap创建一个帮助器Map并使MutableGuiceKeyToInstanceMap extends ForwardingMap将所有内容委托给帮助程序可以工作,但它仍然非常麻烦。还有更好的主意吗?

你认为提议公开ConstrainedMap是一个好主意吗?

2 个答案:

答案 0 :(得分:2)

一些想法:

  1. 我很好奇你为什么要这样做。
  2. ForwardingMap似乎很好。什么是麻烦的?
  3. 公开ConstrainedMap不是一个好主意。

答案 1 :(得分:1)

我不明白为什么你不喜欢ForwardingMapMapConstraint.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