Iterating over a map entryset

后端 未结 6 940
生来不讨喜
生来不讨喜 2020-12-16 13:37

I need to iterate over the entry set of a map from which I do not know its parameterized types.

When iterating over such entryset, why this does not compile ?

<
相关标签:
6条回答
  • 2020-12-16 13:55

    the first code snippet wont compile because the variable map does not exist. You called the parameter anyMap but tried to access it as map, fix that and your code will compile aside from some rawtypes warnings

    0 讨论(0)
  • 2020-12-16 13:55

    You're getting the compile time rrror because you are not specifying the type in HashMap

    Like

    HashMap <(Integer,String> hm=new HashMap<(Integer,String>();  
    

    If you specify the type as Integer and String, you don't get the compile time error.

    IF you Dont Know which Value is going to Add in your HashMap then You Use

    HashMap<(Object,Object> hm=new HashMap();  
    
    0 讨论(0)
  • 2020-12-16 13:58

    In first example, map.entrySet() returns Set, when you iterate in loop you use Iterator. There is no information about set content type, so Java use Object as Object is base type and compiler tells you that it can't convert Object to Entry.

    Set<Map.Entry<K, V>> entrySet();
    

    When you use raw map type, entrySet returns just Set, with no type information.

    In second example, you manualy convert Set to Set<Entry> (with warning). Now Java knows what inside it. So you can iterate.

    In last example you know map type, so entrySet returns correct typed Set and you can iterate without any type conventions.

    0 讨论(0)
  • 2020-12-16 14:08

    It is because you use the raw type Map, therefore map.entrySet() gets you a non-parametrized Set which in return yields Object on iteration, not Entry.

    A simple, but elegant solution is to use Map<?,?>, which will still allow you to pass ANY Map, but on the other hand forces map.entrySet() to have a return value of Set<Entry>:

    public void test(Map<?,?> map) {        
        for(Entry e : map.entrySet()){
            Object key = e.getKey();
            Object value = e.getValue();
        }       
    }
    
    0 讨论(0)
  • 2020-12-16 14:16

    The error you get in your first one is:

    Type mismatch: cannot convert from element type Object to Map.Entry
    

    This is because the compiler converts your FOR-IN loop:

    for (Entry entry : anyMap.entrySet()) {
    }
    

    To:

    for (Iterator i = anyMap.entrySet().iterator(); i.hasNext();) {
        Entry e = i.next(); // not allowed
    }
    

    Your second example works, but only through cheating! You are doing an unchecked cast to get Set back into a Set<Entry>.

    Set<Entry> entries = anyMap.entrySet(); // you get a compiler warning here
    for (Entry entry : entries) {
    }
    

    Becomes:

    Set<Entry> entries = anyMap.entrySet();
    for (Iterator<Entry> i = entries.iterator(); i.hasNext(); ) {
        Entry e = (Entry) i.next(); // allowed
    }
    

    Update

    As mentioned in comments, the type information is getting lost in both examples: because of the compiler's raw type erasure rules.

    To provide backwards compatibility, ALL methods of raw type instances are replaced by their erased counterparts. So, because your Map is a raw type, it all gets erased. Including its Set<Map.Entry<K, V>> entrySet(); method: your raw type instance will be forced to use the erased version: Set entrySet().

    0 讨论(0)
  • 2020-12-16 14:17

    I have faced the same problem. It seems that the casting is a problem. I tried the below code and it worked.

        for(Object entry : hashMap.entrySet())
        {
            System.out.println(((Entry<Object, Object>) entry).getKey() + " = " + ((Entry<Object, Object>) entry).getValue());
    
        }
    
    0 讨论(0)
提交回复
热议问题