简体   繁体   中英

Error while iterating over an ArrayList inside HashMap

I have a HashMap implemented as:

Map<Integer, ArrayList<Integer>> hm = new HashMap<Integer, ArrayList<Integer>>();

After the following operations:

hm.put((Integer) 1, new ArrayList<Integer>());
hm.put((Integer) 2, new ArrayList<Integer>());
(hm.get(1)).add(2);
(hm.get(1)).add(2);
(hm.get(1)).add(3);
(hm.get(2)).add(4);

I get my Map as:

1: [2,2,3]
2: [4]

Now, I want to remove all the occurences of 2 from key 1, ie, I want to modify my HashMap so that it looks like:

1: [3]
2: [4]

I did the following:

for(List<Integer> list : (hm.get(1)))
{
    list.removeAll(Collections.singleton(2));
}

However, while compilation, this error shows up:

error: incompatible types
        for(List<Integer> list : hm.get(1))
                                       ^
required: List<Integer>
found:    Integer
1 error

However, when I run:

System.out.println((hm.get(1)).getClass());

I get:

class java.util.ArrayList

According to which, I think, my code is fine (Even after applying casts, this error shows up in another form).

I don't know as to why this is happening. What am I doing wrong? How to fix this?

Type of variable in the for-each loop should be covariant with the type of the element stored in the Collection you are iterating over.

hm.get(1) will get you the List<Integer> mapped to the key 1 . Iterating over that List<Integer> will get you an Integer , whereas you are trying to store it in a List<Integer> . The for-each variable should be Integer and not List<Integer> . Even better an int , since Integer would anyways be unboxed to an int .

Having said that, there is no need of that loop at all. Just the following code would work:

hm.get(1).removeAll(Collections.singleton(2));

Also, there are some other important issues in your code. For example:

  1. The way you are doing put() :

     hm.put((Integer) 1, new ArrayList<Integer>()); 

    is better written as:

     hm.put(1, new ArrayList<Integer>()); 

    1 will be auto-boxed to Integer wrapper. You don't need to worry about that.

  2. Also, there is no need to surround each method invocation with parenthesis, when you are chaining method calls. So,

     (hm.get(1)).add(2); 

    is better written as:

     hm.get(1).add(2); 
  3. Thirdly, it's better to declare your map as:

     Map<Integer, List<Integer>> hm = new HashMap<Integer, List<Integer>>(); 

    It just provides you the flexibility of adding a LinkedList or an ArrayList or any other implementation inside the map.

You are trying to iterate through your List<Integer> instead of just using it directly. Skip the for loop and just do

hm.get(1).removeAll(Collections.singleton(2));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM