# problem with removing element from HashMap

• 01-09-2010, 03:28 PM
checho
problem with removing element from HashMap
Hi, here is my problem. I have the next task

//Write a program that removes from a given
//sequence all the numbers that present in it odd
//number of times. Example:
//{4, 2, 2, 5, 2, 3, 2, 3, 1, 5, 2} {5, 3, 3, 5}

The problem comes in the last rows where iam trying to remove the element.
It is not happeining.
Why?
How to solve?

Code:

``` import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.Map.Entry; public class Zadacha_7 {           /**         * @param args         */                   //Write a program that removes from a given                 //sequence all the numbers that present in it odd                 //number of times. Example:                 //{4, 2, 2, 5, 2, 3, 2, 3, 1, 5, 2}  {5, 3, 3, 5}           public static void main(String[] args) {                 int[] array = new int[] {-1,0,3,3,3,3,3, 4, 4, 2, 3, 3, 4, 3, 2};                 HashMap<Integer, Integer> numbers = new HashMap<Integer, Integer>();                   for ( int i = 0; i<array.length; i++)                 {                           if (numbers.containsKey(array[i])) {                                 int temp = numbers.get(array[i]);                                 temp++;                                 numbers.put(array[i], temp);                         }                         else {                                 int value =1;                                 numbers.put(array[i], value);                         }                   }                 System.out.println ("Those are the numbers + the number of occuraces " + numbers);                   for (int i : numbers.keySet()){                           if (numbers.get(i) != null) {                                   if (numbers.get(i) %2 == 0){                                         numbers.remove(i);                                   }                                 i--;                         }                        }                   System.out.println (numbers);         }   }```
• 01-09-2010, 03:43 PM
JosAH
You get a ConcurrentModificationExcpetion right? That new-style for-loop uses an Iterator behind your back. Iterators don't like it when you change their Collection behind their back. Use an Iterator yourself (use the EntrySet of the Map and have that Iterator remove the elements yourself.

kind regards,

Jos
• 01-09-2010, 04:07 PM
checho
Yes thats the error that i get
How do i use iterator, i still havent got to it :).
• 01-09-2010, 04:16 PM
JosAH
Quote:

Originally Posted by checho
Yes thats the error that i get
How do i use iterator, i still havent got to it :).

I'm not going to write the code for you: use the keySet of the Map, create an Iterator from it and have it remove the HashMap.Enty elements you want to remove. Also read the API documentation for those classes; it won't hurt ;-)

kind regards,

Jos
• 01-09-2010, 04:44 PM
checho
I read it it doesnt say how to put my hashmap into the iterator, neighter hot to create this iterator. It says only that it has hasnext, next and remove.
I wasted all day on this program, so please dont act like a teacher and just give me what i need if u want to.
For me its easyer to find an answer in google before asking, and i wount waste my time of waiting for answers if i found a solution.
• 01-09-2010, 04:55 PM

In fact, I just answered some question which required an Iterator for the same problem you have.
• 01-09-2010, 05:07 PM
JosAH
Quote:

Originally Posted by checho
I read it it doesnt say how to put my hashmap into the iterator, neighter hot to create this iterator. It says only that it has hasnext, next and remove.
I wasted all day on this program, so please dont act like a teacher and just give me what i need if u want to.
For me its easyer to find an answer in google before asking, and i wount waste my time of waiting for answers if i found a solution.

What if I gave you the code? You don't know how an Iterator works; you don't know how to create one, so my code would be a magic spell to you, you won't understand anything from it. You would turn in the code and get a sufficient grade while you understand zilch from the code. Finally you would graduate and then what? Your co-workers don't want to help you out so your achievements (or lack thereof) will be noticed by your boss(es) and you'll be fired. Don't go that way and start reading the API documentation some more so you'll understand.

kind regards,

Jos
• 01-09-2010, 07:20 PM
checho
Sorry about that, i was upset because iam dealing with this stupid issues all day with no result. I`ll play with it tomorrow again.
• 01-10-2010, 10:12 AM
checho
check this out. I`am using iterator but it still doesn`t remove the element.
But now at least iam not getting the concurent...exception.
What is wront with it now

Code:

```import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.Map.Entry; public class Zadacha_7 {         /**         * @param args         */                         //Write a program that removes from a given                 //sequence all the numbers that present in it odd                 //number of times. Example:                 //{4, 2, 2, 5, 2, 3, 2, 3, 1, 5, 2}  {5, 3, 3, 5}                         public static void main(String[] args) {                 int[] array = new int[] {-1,0,3,3,3,3,3, 4, 4, 2, 3, 3, 4, 3, 2};                 HashMap<Integer, Integer> numbers = new HashMap<Integer, Integer>();                                 for ( int i = 0; i<array.length; i++)                 {                                         if (numbers.containsKey(array[i])) {                                 int temp = numbers.get(array[i]);                                 temp++;                                 numbers.put(array[i], temp);                         }                         else {                                 int value =1;                                 numbers.put(array[i], value);                         }                                 }                 System.out.println ("Those are the numbers + the number of occuraces " + numbers);                 for (int i : numbers.keySet()){                                                 Iterator<Integer> a = numbers.keySet().iterator();                         Integer key = a.next();                                                 System.out.println (key+"is going to be removed");                                                                                         if (key %2 != 0){                                         a.remove();                                 }                 }                         System.out.println (numbers);         } }```
• 01-10-2010, 10:26 AM
JosAH
Quote:

Originally Posted by checho
check this out. I`am using iterator but it still doesn`t remove the element.
But now at least iam not getting the concurent...exception.
What is wront with it now

Code:

```import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.Map.Entry; public class Zadacha_7 {         /**         * @param args         */                         //Write a program that removes from a given                 //sequence all the numbers that present in it odd                 //number of times. Example:                 //{4, 2, 2, 5, 2, 3, 2, 3, 1, 5, 2}  {5, 3, 3, 5}                         public static void main(String[] args) {                 int[] array = new int[] {-1,0,3,3,3,3,3, 4, 4, 2, 3, 3, 4, 3, 2};                 HashMap<Integer, Integer> numbers = new HashMap<Integer, Integer>();                                 for ( int i = 0; i<array.length; i++)                 {                                         if (numbers.containsKey(array[i])) {                                 int temp = numbers.get(array[i]);                                 temp++;                                 numbers.put(array[i], temp);                         }                         else {                                 int value =1;                                 numbers.put(array[i], value);                         }                                 }                 System.out.println ("Those are the numbers + the number of occuraces " + numbers);                 for (int i : numbers.keySet()){                                                 Iterator<Integer> a = numbers.keySet().iterator();                         Integer key = a.next();                                                 System.out.println (key+"is going to be removed");                                                                                         if (key %2 != 0){                                         a.remove();                                 }                 }                         System.out.println (numbers);         } }```

You are building a new Iterator everytime you go through that loop and test the first element it points to. Also, don't use a keySet, use an EntrySet instead; it contains elements of the type HashMap.Entry<Integer, Integer> and it has methods to retrieve the key and the associated value. Read the API documentation for that class and all comes clear ;-)

Basically your code should like this:

Code:

```for (Iterator i= ...; i.hasNext(); ) {   HashMap.Entry<Integer, Integer> entry= i.next();   if (entry.getKey() ...)       i.remove(); }```
kind regards,

Jos
• 01-10-2010, 11:54 AM
checho
Code:

```for (Iterator i= numbers.entrySet().iterator(); i.hasNext(); ) { // iterator should be parametrized                           HashMap.Entry<Integer, Integer> entry= i.next(); // hashmap is not visible                   if (entry.getKey() % 2 != 0)                               i.remove();                         }```
• 01-10-2010, 12:00 PM
JosAH
Quote:

Originally Posted by checho
Code:

```for (Iterator i= numbers.entrySet().iterator(); i.hasNext(); ) { // iterator should be parametrized                           HashMap.Entry<Integer, Integer> entry= i.next(); // hashmap is not visible                   if (entry.getKey() % 2 != 0)                               i.remove();                         }```

Yep, Iterators are generic classes as well; your Iterator walks over HashMap.Entry<Integer, Integer> types so the specialization looks like this:

Code:

`Iterator<HashMap.Entry<Integer, Integer>> i;`
I don't know why a HashMap.Entry<Integer, Integer> should'nt be visible.

kind regards,

Jos
• 01-10-2010, 12:12 PM
checho
Code:

```for (Iterator<HashMap.Entry<Integer, Integer>> i=  [B]// The type HashMap.Entry is not visible[/B] numbers.entrySet().iterator(); i.hasNext(); ) {                           HashMap.Entry<Integer, Integer> entry= (HashMap.Entry) i.next(); [B]//The type HashMap.Entry is not visible[/B]                   if (entry.getKey() % 2 != 0)                               i.remove();                         }                         }```
Any ideas why this is happening
• 01-10-2010, 12:22 PM
JosAH
Quote:

Originally Posted by checho
Any ideas why this is happening

My bad, it should be a Map.Entry, not a HashMap.Entry (you could've found this yourself if you had read the API documentation).

kind regards,

Jos
• 01-10-2010, 01:46 PM
checho
Finally it works fine with a lot of help.
Thanks everyone!
Here is the final code for other "senior" devs like me :)

Code:

```import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import java.util.HashSet; public class Zadacha_7 {         /**         * @param args         */                         //Write a program that removes from a given                 //sequence all the numbers that present in it odd                 //number of times. Example:                 //{4, 2, 2, 5, 2, 3, 2, 3, 1, 5, 2}  {5, 3, 3, 5}                         public static void main(String[] args) {                 int[] array = new int[] {-1,0,3,3,3,3,3, 4, 4, 2, 3, 3, 4, 3, 2};                 HashMap<Integer, Integer> numbers = new HashMap<Integer, Integer>();                                 for ( int i = 0; i<array.length; i++)                 {                                         if (numbers.containsKey(array[i])) {                                 int temp = numbers.get(array[i]);                                 temp++;                                 numbers.put(array[i], temp);                         }                         else {                                 int value =1;                                 numbers.put(array[i], value);                         }                                 }                 System.out.println ("Those are the numbers + the number of occuraces " + numbers);                 for (Iterator<Map.Entry<Integer, Integer>> i= numbers.entrySet().iterator(); i.hasNext(); ) {                           Map.Entry<Integer, Integer> entry= i.next();                                             if ((entry.getValue()+2) % 2 != 0) {                                                       i.remove();                         }                         }                                 System.out.println ("Result - numbers with even occurances" + numbers);                         } }```
• 01-10-2010, 02:10 PM
JosAH
A little tip: you coud've used a Set<Integer> and alternately add/remove numbers to/from it when you read it in your list; if a number occurs an odd number of times it'll be present in your set, otherwise it won't. That gets rid of that last loop over the entry set.

kind regards,

Jos