0

I have a method test(), in which I am trying to compare two LinkedHashMaps against each other and modify the contents of one of the maps by removing the key/value pair if it is found in both LHM's. I keep getting a ConcurrentModificationException when running this method. I understand WHY I am getting the exception (since I am trying to modify the list that is being looped over). I'm not sure how to go forth with this however. I have this code so far:

private void test() {    

LinkedHashMap<String, BigDecimal>testBene = new LinkedHashMap<String, BigDecimal>();
LinkedHashMap<String, BigDecimal>testDly = new LinkedHashMap<String, BigDecimal>();

testBene.put("ABCDEFG", BigDecimal.ZERO);
testBene.put("BCDEFGH", BigDecimal.ONE);
testBene.put("CDEFGHI", BigDecimal.TEN);

testDly.put("BCDEFGH", BigDecimal.ONE);
testDly.put("Foo", BigDecimal.TEN);
testDly.put("Bar", BigDecimal.TEN);

for (Entry<String, BigDecimal> beneKeySet : testBene.entrySet()) {
    if (testDly.containsKey(beneKeySet.getKey())) {
        for (Entry<String, BigDecimal> dlyKeySet : testDly.entrySet()) {
            if ((dlyKeySet.getKey().equals(beneKeySet.getKey())) && 
                dlyKeySet.getValue().equals(beneKeySet.getValue())) {
                    testBene.remove(dlyKeySet.getKey());
            }
        }
    }
}

}
ResourceReaper
  • 555
  • 2
  • 10
  • 27
  • 2
    Are you aware that you are comparing strings with `==` instead of `.equals()` ? See [How do I compare strings in Java?](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – jlordo Apr 04 '13 at 12:56
  • @jlordo Yes I am, and I fixed for efficiency. Sorry, like I said it was just a test. – ResourceReaper Apr 04 '13 at 13:11
  • `==` is probably more efficient, but it's not guaranteed to be true for two strings with identical content. – jlordo Apr 04 '13 at 13:13
  • @jlordo, you are right, I stand corrected. == is more efficient. – ResourceReaper Apr 04 '13 at 13:47

4 Answers4

2

Instead of removing the elements, put the keys that you want to remove into a separate collection. At the end, traverse that other collection, removing the keys from your map.

Alternatively, use the Iterator interface instead of the for-each loop. This will enable you to use Iterator.remove() to remove elements while iterating.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

You cannot remove from a list you're currently iterating with a for each. Use the list's iterator to do this.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
1

You could use an iterator:

for (Iterator<Entry<String, BigDecimal>> it = testBene.entrySet().iterator(); it.hasNext();) {
    Entry<String, BigDecimal> beneKeySet = it.next();
    if (testDly.containsKey(beneKeySet.getKey())) {
        for (Entry<String, BigDecimal> dlyKeySet : testDly.entrySet()) {
            if ((dlyKeySet.getKey() == beneKeySet.getKey()) && dlyKeySet.getValue() == beneKeySet.getValue()) {
                it.remove();
            }
        }
    }
}
sp00m
  • 47,968
  • 31
  • 142
  • 252
  • this is the answer, I guess that I'm not that good at iterators. I did read that the only way to solve the CMEx, was to use one. I was trying to figure out how to write the code to do so. I tested it and it works, now I just need to walk through your code and see the why. Thank you very much. – ResourceReaper Apr 04 '13 at 13:10
0

You can use EntrySet's iterator, or save all duplicated keys in another list, and later remove those from the map. Also, do not compare objects using ==, use the equals() function.

Luciano
  • 8,552
  • 5
  • 32
  • 56