Java 为什么使用HashMap<;字符串,对象>;不接受HashMap<;字符串,列表>;实例?
我是java泛型新手,面临以下问题。 我有这样的方法Java 为什么使用HashMap<;字符串,对象>;不接受HashMap<;字符串,列表>;实例?,java,generics,collections,Java,Generics,Collections,我是java泛型新手,面临以下问题。 我有这样的方法 private static void fillDescriptiveData(HashMap<String, Object> output, String attributeMapping) { for (Map.Entry<String, Object> outputInEntry : output.entrySet()) { String outputKey = outputInEntry
private static void fillDescriptiveData(HashMap<String, Object> output, String attributeMapping) {
for (Map.Entry<String, Object> outputInEntry : output.entrySet()) {
String outputKey = outputInEntry.getKey();
String outputValue = outputInEntry.getValue().toString();
outputValue = getDescriptiveDataForOutput(outputKey, outputValue, attributeMapping);
outputInEntry.setValue(outputValue);
}
}
第-outputInEntry.setValue(outputValue)行出错代码>
类型中的方法setValue(捕获#4-of?扩展对象)
地图。条目不适用于
参数(字符串)
为什么?
避免此问题的最佳方法是什么?在这种情况下,您可以使用类型变量:
private static <T> void fillDescriptiveData(Map<String, T> output,String attributeMapping)
{
for(Map.Entry<String, T> outputInEntry : output.entrySet())
{
String outputKey = outputInEntry.getKey();
String outputValue = outputInEntry.getValue().toString();
outputValue = getDescriptiveDataForOutput(outputKey, outputValue, attributeMapping);
outputInEntry.setValue((T) outputValue);
}
}
private static void fillDescriptiveData(映射输出,字符串属性映射)
{
for(Map.Entry outputInEntry:output.entrySet())
{
字符串outputKey=outputInEntry.getKey();
字符串outputValue=OutputEntry.getValue().toString();
outputValue=getDescriptiveDataForOutput(outputKey、outputValue、attributeMapping);
setValue((T)outputValue);
}
}
更具体地说,映射中的第二个类型参数是无界的<代码>对象
在这里不起作用,因为它是特定的类<代码>?扩展对象有点胡说八道。
只要HashMap
就可以了,直到你读了地图,但是你不能把东西放在这里。所以只有一种方法-使用类型变量
编辑:还有一件事:请尽可能使用接口。因此,这里最好使用
Map
而不是HashMap
。这不是一个错误,只是好的和适当的代码样式。这一行的错误:
outputInEntry.setValue(outputValue);
您总是在条目中放入字符串。仅当条目类型为?超级字符串
,或者确切地说是字符串
。因此,它不适用于映射
或映射
似乎您只想将每个值映射到一个字符串。您可以这样做,但为了确保类型安全,您需要创建一个新的映射。因为您总是映射到字符串
例如,如果您传入一个传递到函数中的Map>
,但它现在包含字符串作为值而不是列表。当他们试图从中检索列表时,他们会得到一个类强制转换异常
大概是这样的:
private static Map<String, String> fillDescriptiveData(HashMap<String, ?> input,
String attributeMapping) {
Map<String, String> output = new HashMap<>();
for(Entry<String, ?> e : input.entrySet()) {
String outputKey = e.getKey();
String outputValue = e.getValue().toString();
outputValue
= getDescriptiveDataForOutput(outputKey, outputValue, attributeMapping);
output.put(outputKey, outputValue);
}
return output;
}
私有静态映射fillDescriptiveData(HashMap输入,
字符串属性映射){
映射输出=新的HashMap();
对于(条目e:input.entrySet()){
字符串outputKey=e.getKey();
字符串outputValue=e.getValue().toString();
输出值
=getDescriptiveDataForOutput(outputKey、outputValue、attributeMapping);
put(outputKey,outputValue);
}
返回输出;
}
Map r1=fillDescriptiveData(ObjectMap,“此处”);
映射r2=fillDescriptiveData(列表映射,“此处”);
您的第二个“为什么?”问题是“为什么我不能将字符串作为值放入映射中”
,答案是“因为静态类型系统正在完成它的工作。”“。无论如何,你试图做的显然是不好的,你的方法fillDescriptiveData
将你的HashMap
转换为HashMap
,这显然是一种违反,不要使用泛型,如果您想将西红柿转换成胡萝卜并将结果放入同一个集合中,只需使用raw type,类似于Map getDescriptiveData(HashMap输出,字符串属性映射){…}
?-此外,你的问题标题具有误导性;您可能想编辑它。显然,您希望字符串outputValue
可以转换为任意T
@MarkoTopolnik。我同意,这很奇怪,我没有注意到。但它会起作用,因为在运行时,您可以将任何值放入映射:)有意义的方法签名是Map Map,T value)
,但这似乎不是OP的目的。他似乎是在做一件非常不明智的事情。”?extensed Object
有点胡说八道“其实这不是一种未知的对象类型,它相当于?
我们称之为代价高昂的胜利:)这种说法“这只会起作用”是不准确的。正如我在回答中所说,它将与类型变量一起工作。类型的实际不匹配并不是关键问题,因为运行时映射可以保存任何类型的值types@Andremoniy当然,也许我应该加上“适当”或“以类型安全的方式”。
outputInEntry.setValue(outputValue);
private static Map<String, String> fillDescriptiveData(HashMap<String, ?> input,
String attributeMapping) {
Map<String, String> output = new HashMap<>();
for(Entry<String, ?> e : input.entrySet()) {
String outputKey = e.getKey();
String outputValue = e.getValue().toString();
outputValue
= getDescriptiveDataForOutput(outputKey, outputValue, attributeMapping);
output.put(outputKey, outputValue);
}
return output;
}
Map<String, String> r1 = fillDescriptiveData(ObjectMap, "here");
Map<String, String> r2 = fillDescriptiveData(listMap, "here");