在JAVA中删除二维TreeMap中的实例

时间:2015-03-10 11:00:39

标签: java treemap

您好,我正在为我的学校做作业,并尝试从二维TreeMap<String, TreeMap<Date, Integer>中移除实例并保持其结构相同

我应该这样做的功能:

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);
            }
        }
    }
}

我的地图看起来像这样

<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>>

当从我的函数中删除时,删除了第一次出现的apple并且应该转到第二次崩溃时崩溃:

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)

位于内部for循环上(for(Date d:produkt.keySet()))

任何想法为什么会崩溃?

3 个答案:

答案 0 :(得分:2)

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

在迭代时,您无法从集合中删除元素,这会导致错误。


您应该使用TreeMap来保持元素顺序的事实,因此您的商品已根据Date进行排序!

您可以将此事实简单地用于代码并使用tailMap()功能并获取仅包含具有更高日期的键的子图。

这可以完成,而不是修改现有的地图 - 使用上述方法创建一个新地图,并将其放在原始树中。

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

请注意,在迭代时修改(外部地图)不会导致此异常。

答案 1 :(得分:0)

它正在崩溃,因为您在隐式迭代树图时尝试删除元素(因为它会影响内部迭代索引)。您应该在临时数据结构中保留要删除的键,并在迭代树映射后删除键。

答案 2 :(得分:0)

使用Iterator代替内循环:

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