6

I know there are several ways to iterate through a hashmap, but what is a good way to modify a hashmap as you go along (other than just creating a new hashmap and getting rid of the old one)

I want something like

for (Map.Entry<String, Integer> entry : wordcounts.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    if(blacklist.contains(key))
        //remove key/value for that key from wordcounts
    if(mappings.contains(key))
     //change key in wordcounts from one string to another based on the key's value in a <string,string> map (mappings)
}

Will it be possibly for me to modify my map while I'm going through it? Do i have to use an iterator?

LemonMan
  • 2,963
  • 8
  • 24
  • 34
  • You use the `Iterator` to remove entries as you come upon them. Changing the key value is going to require creating a new `Map` and either copying the unchanging values or modifying and inserting the changing ones. The cost in time and memory isn't too large if you remove them from the old `Map` as you add to the new one. – Lee Meador Jul 08 '13 at 17:20
  • fair enough, i will be doing these particular modifications on a small map so it may be simpler to create a new map – LemonMan Jul 08 '13 at 17:23
  • @LeeMeador I did look at the post at length, though it specified how to remove elements, not modify keys, but if i simply create a new map i guess it isn't an issue – LemonMan Jul 08 '13 at 17:23
  • i may end up needing to use the iterator to remove words below a certain length – LemonMan Jul 08 '13 at 17:28

3 Answers3

3

Take advantage of the map: go through your other collections first and do your operations.

for(String blacklisted : blacklist) {
    wordcounts.remove(blacklisted);
}
for(String mapping : mappings) {
    String oldKey =    // get old key
    String value = wordcounts.get(oldKey);
    wordcounts.remove(oldKey);
    wordcounts.put(mapping, value);
}
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
1

Use Map.Entry.setValue to change the value of the mapping. If you want to remove the mapping, use setValue(null) use an Iterator.

Jeffrey
  • 44,417
  • 8
  • 90
  • 141
  • On second thought, using `setValue(null)` might not remove the mapping. I'll test this and get back to you. – Jeffrey Jul 08 '13 at 17:21
  • yeah looking through javadocs looks like it might just set the value to null – LemonMan Jul 08 '13 at 17:21
  • (though i think there is a map.remove(key) option) – LemonMan Jul 08 '13 at 17:24
  • @Lemonio Yeah, `setValue(null)` just sets the mapping to `null`. If you tried to use `Map.remove(key)` while iterating, you would get a `ConcurrentModificaitonException`. – Jeffrey Jul 08 '13 at 17:25
  • yeah that's what i thought from the other threads but vakh's suggestion for removing seems like a good way to go – LemonMan Jul 08 '13 at 17:26
0

Don't try to remove items during the iteration or you'll get an exception out of the iterator. Best bet is to either

a) clone the map by iterating/copying into a new map or b) keeping track as you go along of items to be removed and removing them after you're done iterating.

If you're changing keys, same thing applies.. keep track as you go and do the remove/add after you're done iterating.

If you're just changing values, just go for it.

ticktock
  • 1,593
  • 3
  • 16
  • 38