Search code examples
javatreemap

Removing instance in two-dimensional TreeMap in JAVA


Hi I'm doing homework for my school and am trying to remove instance from two-dimensional TreeMap<String, TreeMap<Date, Integer> and keep it the same structure

my function that is supposed to do that :

public void vyhodExpirovane(){
    Date now = new Date(System.currentTimeMillis());
    TreeMap<Date, Integer> produkt;
    System.out.println(now);
    for (String name: obsah.keySet()){
        produkt = obsah.get(name);
        System.out.print(name + " pocet roznych" + produkt.size() + " datum");
        for (Date d: produkt.keySet()){
            System.out.println( d + " pocet:" + produkt.get(d));
            if (d.before(now)) {
                obsah.get(name).remove(d);
            }
        }
    }
}

and my map looks like this

<cheese , <Mar 10 10:58:02 CET 2015, 1>>
<apple , <Mar 10 10:58:02 CET 2015, 1> <Mar 10 11:58:02 CET 2015, 2>>

when the remove from my function removes first occurance of apple and is supposed to go to second it crashes with:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source)
at java.util.TreeMap$KeyIterator.next(Unknown Source)
at Chladnicka.vyhodExpirovane(Chladnicka.java:126)
at MainClass.main(MainClass.java:46)

which is on the inner for loop (for (Date d: produkt.keySet()))

any idea why is it crashing?


Solution

  •     for (Date d: produkt.keySet()){
            System.out.println( d + " pocet:" + produkt.get(d));
            if (d.before(now)) {
                obsah.get(name).remove(d);
            }
        }
    

    You cannot remove an element from a collection while iterating it, this is causing the error.


    You should use the fact that you have TreeMap, that maintains order of the elements, so your items are already sorted according to Date!

    You can use this fact to simply your code and use the tailMap() functionality and get a submap that include only keys with higher dates already.

    This can be done instead of modifying your existing map - create a new one using the mentioned method, and put it in the original tree.

     obsah.put(name, obsah.get(name).tailMap(now))
    

    Note that modifying a value (of the outer map) while iterating does not cause this exception.