6

是否可以声明一个从特定子类的键映射到特定子类的值但确保两个类共享相同类型参数的 Map?

对于背景:

ClassA 和 ClassB 都实现了公共资源的行为

public abstract  class ClassA<T> {
      public abstract T getResource() ;
}

public abstract class classB<T> {
       public  abstract void consoumeResource(T resource);
}

我想从 ClassA 和 ClassB 的实现中进行映射,并确保只有“兼容”对可以放在一个条目中。

4

2 回答 2

5

另一种方法是提供您自己的Map实现。如果您扩展现有实现并使用新类型,则不需要太多代码:

public class CompatibleHashMap<T> extends HashMap<ClassA<T>, ClassB<T>> {

}

现在, a CompatibleHashMap<String>only 允许您将ClassA<String>其作为键和ClassB<String>值。

编辑:

正如您在评论中提到的那样,这样您就可以将自己与Map实现联系起来。您可以通过执行以下操作来克服此问题:

public class CompatibleMap<T> implements Map<ClassA<T>, ClassB<T>> {

    private Map<ClassA<T>, ClassB<T>> map;

    public CompatibleMap(Map<ClassA<T>, ClassB<T>> map) {
        this.map = map;
    }

    @Override
    public Set<List<T>> keySet() {
        return map.keySet();
    }
    // ... implement all other Map methods by calling the method on map.
}

然后你可以像这样实例化它

CompatibleMap<String> map = new CompatibleMap<>(new HashMap<ClassA<String>, ClassB<String>>());

这样,您就不会被绑定到特定的实现,如果,和Map的泛型类型不同,编译器将抛出错误。mapClassAClassB

于 2013-01-23T10:15:21.300 回答
4

您不能在 Map 声明中执行此操作,但您可以使用访问/更新地图的方法执行此操作。

例如

private final Map<Class, Builder> builderMap = new LinkedHashMap<>();

public <T> void addBuilder(Class<T> tClass, Builder<T> tBuilder) {
     builderMap.put(tClass, tBuilder);
}

public <T> Builder<T> getBuilderFor(Class<T> tClass) {
    @SuppressWarnings("unchecked") 
    Builder<T> tBuilder = (Builder<T>) builderMap.get(tClass);
    return tBuilder;
}
于 2013-01-23T10:09:55.820 回答