简体   繁体   English

Java:使用两个相关泛型类型声明一个映射( <T> 地图 <Class<? extends ClassA<T> &gt;,类 <? extends ClassB<T> &gt;&gt;)

[英]Java: Declaring a Map with two related generics Types (<T> Map<Class<? extends ClassA<T>>,Class<? extends ClassB<T>>>)

Is it possible to declare a Map that maps from keys of a specific subclass to values of a specific subclass but ensuring that both classes share the same Type parameter? 是否可以声明一个Map,该Map从特定子类的键映射到特定子类的值,但确保两个类共享相同的Type参数?

For the background: 对于背景:

both ClassA and ClassB implement behaviour for a common resource ClassA和ClassB都实现了公共资源的行为

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

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

i want to map from implementations of ClassA and ClassB and ensure only "compatible" pairs can be put together in one entry. 我想映射ClassA和ClassB的实现,并确保只有“兼容”对可以放在一个条目中。

Another way would be to provide your own Map implementation. 另一种方法是提供自己的Map实现。 There's not much code needed if you extend an existing implementation, and use your new type: 如果扩展现有实现并使用新类型,则不需要太多代码:

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

}

Now, a CompatibleHashMap<String> only lets you put ClassA<String> as keys and ClassB<String> as values. 现在, CompatibleHashMap<String>只允许您将ClassA<String>作为键,将ClassB<String>作为值。

EDIT: 编辑:

As you mentioned in your comment, this way you are tying yourself to a Map implementation. 正如您在评论中提到的那样,这样您就可以将自己与Map实现联系起来。 You can overcome this by doing something like the following: 您可以通过执行以下操作来解决此问题:

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.
}

You can then instantiate it like 然后你可以实例化它

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

This way, you are not tied to a specific Map implementation, and the compiler will throw an error if the generic types of the map , ClassA and ClassB are not the same. 这样,您不依赖于特定的Map实现,如果map的泛型类型ClassAClassB不相同,编译器将抛出错误。

You can't do this in the Map declaration but you can do this using methods which access/update the map. 您不能在Map声明中执行此操作,但可以使用访问/更新地图的方法执行此操作。

eg 例如

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM