我有以下地图。两个地图都将ClassA/ClassB
的实例和CellProcessor
的实例保存为值。
Map<ClassA, CellProcessor> classAProcessors;
Map<ClassB, CellProcessor> classBProcessors;
我想创建一个地图,将地图上方的地图存储为值,并将密钥存储为ClassA/ClassB
的类类型,这样当我执行map.get(ClassA.class)
时,它会返回Map<ClassA, CellProcessor> classAProcessors
我写了这个方法来创建最终地图,但它似乎没有用。
public static <T> Map<Class<T>, Map<T, CellProcessor>> getOutputProcessors(){
Map<ClassA, CellProcessor> classAProcessors = getOutputCellProcessorsForClassA();
Map<Class<T>, Map<T, CellProcessor>> processors = Maps.newLinkedHashMap();
processors.put(ClassA.class, classAProcessors ); //error here
return processors;
}
编译错误:
The method put(Class<T>, Map<T,CellProcessor>) in the type Map<Class<T>,Map<T,CellProcessor>> is not applicable for the arguments (Class<ClassA>, Map<ClassA,CellProcessor>)
有人可以帮我理解这里的错误。
谢谢
答案 0 :(得分:1)
ClassA和ClassB不能在同一类型的地图中。要做到这一点,你需要一个异构的映射(可以有任何类型的对象),因此它需要是一个没有类型参数的HashMap(或者?或Object作为参数)。
但是,如果ClassA和ClassB共享相同的超类型,那么您可以为该共享超类型创建一个映射。
不,如果我误解了你只想要一个与classB分开的地图地图,那么你需要两种方法。您不能像使用C ++模板那样使用泛型重载实现。
因此,您将需要具有不同名称的方法,其中一个返回ClassA的地图地图,另一个返回ClassB的地图。它们不能具有相同的名称,并且属于同一类,但专门针对不同类型。
答案 1 :(得分:1)
编译器报告错误,因为您尝试将具有不兼容类型的条目添加到地图processors
。在编译时,编译器不知道T
的类型是什么。类型T
将由使用方法getOutputProcessors
的客户端确定。方法processors.put
期望第一个参数恰好是Class<T>
的类型(T
将仅由使用方法getOutputProcessors
的代码确定),但是您总是通过ClassA.class
的值相同。方法processors.put
的第二个参数也是不正确的,它应该是Map<T, CellProcessor>
的类型,并且您永久传递类型为Map<ClassA, CellProcessor>
的参数。将类型T
视为独立类型,因此在方法代码中T
不等同于ClassA
。您的方法的正确版本应如下所示:
public static <T> Map<Class<T>, Map<T, CellProcessor>> getOutputProcessors(Class<T> key, Map<T, CellProcessor> classProcessors) {
Map<Class<T>, Map<T, CellProcessor>> processors = new HashMap<Class<T>, Map<T, CellProcessor>>();
processors.put(key, classProcessors);
return processors;
}
您可以通过以下方式使用此方法:
Map<Class<ClassA>, Map<ClassA, CellProcessor>> processorsA = getOutputProcessors(ClassA.class, classAProcessors);
Map<Class<ClassB>, Map<ClassB, CellProcessor>> processorsB = getOutputProcessors(ClassB.class, classBProcessors);
但是通过这种方式,地图processorsA
和processorsB
不兼容,您将无法将它们合并到一个地图中。因此,您需要使用与Map<Class<T>, Map<T, CellProcessor>>
不同的地图类型
最好的方法是创建(或者如果已经存在)ClassA
和ClassB
的超类型(例如,名称为ClassBase
的类或接口)。使用超类getOutputProcessors
的{{1}}方法如下所示:
ClassBase
如果由于某种原因你不能在你的代码中使用超类ClassBase,那么你可以使用如下所示的方法:
public static Map<Class<? extends ClassBase>, Map<? extends ClassBase, CellProcessor>> getOutputProcessors() {
Map<Class<? extends ClassBase>, Map<? extends ClassBase, CellProcessor>> processors =
new HashMap<Class<? extends ClassBase>, Map<? extends ClassBase, CellProcessor>>();
processors.put(ClassA.class, getOutputCellProcessorsForClassA());
processors.put(ClassB.class, getOutputCellProcessorsForClassB());
return processors;
}
我希望我的回答能帮到你
答案 2 :(得分:0)
为什么要添加<T>
,上课就足够了。
如果您想使用<T>
将其更改为并使ClassA和ClassB扩展为baseClass。
答案 3 :(得分:0)
public static Map<Class, Map<Object, CellProcessor>> getOutputProcessors() {
Map<Class, Map<Object, CellProcessor>> processors = Maps.newLinkedHashMap();
processors.put(ClassA.class, getOutputCellProcessorsForClassA);
return processors;
}