0

I am trying to enter the below statement into HashMap

Input Line: Rainy#No:2 Sunny#No:3 Rainy#Yes:3 Sunny#Yes:2 Overcast#Yes:4
Expected Output:{Rainy={No=2,Yes=3},Rainy={No=3,Yes=2},Overcast={Yes=4}}

What I did so far is

import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


public class StackHash{

/**
*@paramargs
*/

staticConcurrentMap<String,HashMap<String,Integer>>map=newConcurrentHashMap<>();
public static final String TAB="\t";
public static final String SPACE=" ";
public static final String HASH="#";
public static final String COLON=":";
public static void main(String[]args){
//TODOAuto-generatedmethodstub

Stringline="Rainy#No:2 Sunny#No:3 Rainy#Yes:3 Sunny#Yes:2 Overcast#Yes:4";
StringTokenizerst=newStringTokenizer(line,SPACE);
HashMap<String,Integer>attibuteCollect=newHashMap<String,Integer>();
while(st.hasMoreTokens()){
 Stringtoken1=st.nextToken();
 String[]parts=token1.split(HASH);
 String[]parts1=parts[1].split(COLON);
 attibuteCollect.put(parts1[0],Integer.parseInt(parts1[1]));
 if(map.isEmpty()){
   map.put(parts[0],attibuteCollect);
 }
 else{
   for(Map.Entry<String,HashMap<String,Integer>>entry:map.entrySet()){
     StringkeyMap=entry.getKey();
     if(keyMap.equals(parts[0])){
       map.put(keyMap,attibuteCollect);
     }
     else{
       map.put(parts[0],attibuteCollect);
     }
 }
}
}
System.out.println("finalmap"+map);
}
}

Output

map {Rainy={Yes=4, No=3}, Sunny={Yes=4, No=3}, Overcast={Yes=4, No=3}}

Am I doing anything wrong.

Please Suggest.

USB
  • 6,019
  • 15
  • 62
  • 93
  • 1
    @Makoto This is not the exact duplicate. The duplicate marked question explaining about removing the item from map. Here in this case there is no remove method calling on iterator. Am I wrong ? – Suresh Atta Jun 04 '14 at 06:49
  • @sᴜʀᴇsʜᴀᴛᴛᴀ The question applies to any structural modification of a collection while you are iterating over it. Sure, `Map#put()` is being called instead of `map.remove()`, but the cause of the problem is exactly the same. – awksp Jun 04 '14 at 07:04
  • @user3580294 I Got your point and now I'm not seeing any `ConcurrentModificationException` in OP's question :) – Suresh Atta Jun 04 '14 at 07:06
  • @sᴜʀᴇsʜᴀᴛᴛᴀ Guess now that OP's question changed the point is moot... Although according to the javadoc `ConcurrentModificationExceptions` are not guaranteed to be thrown, and even then this code has undefined behavior, so this code not working right isn't that surprising to me – awksp Jun 04 '14 at 07:10
  • 1
    @user3580294 Thumbs up. Agreed. I tried to execute current code and giving some other exception :) Mismatching every where. – Suresh Atta Jun 04 '14 at 07:14
  • After changing to ConcurrentMap also the values in inner hashmap is getting overwritten – USB Jun 04 '14 at 07:30

1 Answers1

0

Reason:

You got ConcurrentModificationException because, you have modified inner attibuteCollect map using put method while iterating over outer map.

Solution:

Use ConcurrentHashMap insted of HashMap to solve ConcurrentModificationException.

  ConcurrentMap<String, HashMap<String,Integer>> map = new ConcurrentHashMap<>();
Masudul
  • 21,823
  • 5
  • 43
  • 58
  • @Masud: It didnt solved.again getting the same output final map {Rainy={Yes=4, No=3}, Sunny={Yes=4, No=3}, Overcast={Yes=4, No=3}} – USB Jun 04 '14 at 06:55
  • I think I have done some mistake in looping.but not able to fix it – USB Jun 04 '14 at 06:56
  • @SreeVeni, Yes that is mistake. Please debug your code and see how your value changed. – Masudul Jun 04 '14 at 06:58
  • @SreeVeni Can you set up a IDEONE for your problem. Please give some working code. Running your code causing a different exception `java.lang.NumberFormatException: For input string: "2 Sunny"` – Suresh Atta Jun 04 '14 at 07:04
  • @Masud: I edited the code as you suggested – USB Jun 04 '14 at 08:04