joasisk
joasisk

Reputation: 61

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?

Upvotes: 0

Views: 593

Answers (3)

giorashc
giorashc

Reputation: 13713

It is crashing because you try to remove an element while you implicitly iterating your tree map (as it affects the internal iteration index). You should keep the keys you want to remove in a temporary data structure and remove the keys after iterating the tree map.

Upvotes: 0

amit
amit

Reputation: 178461

    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.

Upvotes: 2

Alex Salauyou
Alex Salauyou

Reputation: 14338

Use Iterator instead of inner loop:

Iterator<Map.Entry<Date, Integer>> i = produkt.entrySet().iterator();
Map.Entry<Date, Integer> e;
while (i.hasNext() && (e = i.next()) != null) {
    if (e.getKey().before(now)) {
         i.remove();
    }
}

http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html#entrySet%28%29

Upvotes: 0

Related Questions