[英]why HashMap<String, Object> not accept HashMap<String, List> instance?
I am new in java generics and facing following issues. 我是Java泛型的新手,面临以下问题。 I have have method like, 我有这样的方法,
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);
}
}
Now if I call API as below way 现在,如果我按以下方式调用API
HashMap<String, Object> ObjectMap = new HashMap<String, Object>();
HashMap<String, List> listMap = new HashMap<String, List>();
fillDescriptiveData(ObjectMap,"here");
this one working fine. 这个工作正常。
fillDescriptiveData(listMap,"here");
this call gives error 这个电话给错误
The method fillDescriptiveData(HashMap, String) in the type CustomAttribute is not applicable for the arguments (HashMap, String)` CustomAttribute类型的方法fillDescriptiveData(HashMap,String)不适用于参数(HashMap,String)`
why ? 为什么呢?
In row to solve this issue I encounter with one more issue, 为了解决这个问题,我遇到了又一个问题,
private static void fillDescriptiveData(HashMap<String, ? extends Object> output, String attributeMapping) {
for (Map.Entry<String, ? extends Object> outputInEntry : output.entrySet()) {
String outputKey = outputInEntry.getKey();
String outputValue = outputInEntry.getValue().toString();
outputValue = getDescriptiveDataForOutput(outputKey, outputValue, attributeMapping);
outputInEntry.setValue(outputValue); /* Error comes at this line */
}
}
HashMap<String, ? extends Object> ObjectMap = new HashMap<String, Object>();
HashMap<String, List> listMap = new HashMap<String, List>();
fillDescriptiveData(ObjectMap,"here");
fillDescriptiveData(listMap,"here");
error at line - outputInEntry.setValue(outputValue);
行错误outputInEntry.setValue(outputValue);
The method setValue(capture#4-of ? extends Object) in the type Map.Entry is not applicable for the arguments (String) Map.Entry类型的方法setValue(capture#4-of?extended Object)不适用于参数(String)
why ? 为什么呢?
What is the best way to avoid this issues ? 避免此问题的最佳方法是什么?
This is the case when you could use type variables: 当您可以使用类型变量时就是这种情况:
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);
}
}
More specifically, your second type-parameter in the map is unbounded. 更具体地说,地图中的第二个类型参数是无界的。 Object
will not work here as it is specific class. Object
在这里不起作用,因为它是特定类。 ? extends Object
? extends Object
is somewhat nonsense. ? extends Object
有点废话。 Just HashMap<String, ?>
would work until you will just read the map, but you will not be able to put something here. 只有HashMap<String, ?>
可以工作,直到您仅阅读地图,但是您将无法在此处放置东西。 So only one way - using type variable. 所以只有一种方法-使用类型变量。
EDIT : One more thing: please, use interfaces where it's possible. 编辑 :还有一件事:请在可能的地方使用接口。 So here instead of HashMap<String, T>
better use Map<String, T>
. 因此,这里最好使用Map<String, T>
而不是HashMap<String, T>
Map<String, T>
。 It isn't a mistake, just good and proper style of code. 这不是错误,只是良好而适当的代码风格。
The error with this line: 此行的错误:
outputInEntry.setValue(outputValue);
Is that you're always putting a string into the entry. 是您总是在输入字符串。 This will only work if the entry is of type ? super String
仅当条目类型为? super String
此方法才有效? super String
? super String
, or exactly String
. ? super String
或完全String
。 So it will not work for a Map<String, Object>
or Map<String, List>
. 因此,它不适用于Map<String, Object>
或Map<String, List>
。
It seems like you just want to map each value to a string. 似乎您只想将每个值映射到一个字符串。 You can do it, but to be type safe, you need to create a new Map<String, String>
. 您可以执行此操作,但是为了确保输入的安全性,您需要创建一个新的Map<String, String>
。 Since you're always mapping to a String
. 由于您总是映射到String
。
If you for instance pass in a Map<String, List<?>>
and (unsafely) replace all the values with strings. 例如,如果您传入Map<String, List<?>>
和(不安全地)将所有值替换为字符串。 Someone could still keep using the Map<String, List<?>>
that was passed into the function, but it now contains strings as values instead of lists. 仍然有人可以继续使用传递给函数的Map<String, List<?>>
,但是现在它包含字符串而不是列表作为值。 When they try to retrieve a List
from it they get a class cast exception. 当他们尝试从中检索List
时,会收到类强制转换异常。
Something like this: 像这样:
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");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.