简体   繁体   English

为什么选择HashMap <String, Object> 不接受HashMap <String, List> 实例?

[英]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.

相关问题 检查Object是否是String,HashMap或HashMap []的实例 - Check if Object is instance of String, HashMap, or HashMap[ ] 哈希表<String,List<String> &gt; 到 HashMap <Object,List<String> &gt; 使用流 - HashMap<String,List<String>> to HashMap<Object,List<String>> using streams 允许JComboBox接受列表 <String> 或HashMap而不是String [] - Allow JComboBox to accept List<String> or HashMap instead of String[] 如何使用 stream 过滤器获取 hashmap 列表? ArrayList <hashmap<string, object> &gt; </hashmap<string,> - How use stream filter for list of hashmap? ArrayList<HashMap<String, Object>> HashMap的两个实例之间的区别 <String, String> 和HashMap的实例 <String,Object> 其中对象包含两个字符串 - Difference between two instances of HashMap<String, String> and an instance of HashMap<String,Object> where Object contains the two Strings 转换清单 <HashMap<String, Object> &gt;串流 - Convert List<HashMap<String, Object>> to stream 按键值排序列表&lt;HashMap &lt;String,Object &gt;&gt; - Sort List < HashMap < String, Object >> by value of key List <HashMap <String,Object >>的Thrift类型建模 - Thrift type modelling for List<HashMap<String,Object>> 整数对象 <String, String> 哈希图 - Integer object in a <String, String> hashmap 转换HashMap <String, String> 到HashMap <String, List<String> &gt;() - Transform HashMap<String, String> to HashMap<String, List<String>>()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM