JAVA 中的二维 TreeMap 中删除实例
Removing instance in two-dimensional TreeMap in JAVA
嗨,我正在为我的学校做作业,我正在尝试从二维中删除实例 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()))
知道为什么会崩溃吗?
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))
请注意,在迭代时修改 value(外部映射的)不会导致此异常。
它正在崩溃,因为您在隐式迭代树图时试图删除一个元素(因为它会影响内部迭代索引)。您应该将要删除的键保存在临时数据结构中,并在迭代树图后删除键。
使用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
嗨,我正在为我的学校做作业,我正在尝试从二维中删除实例 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()))
知道为什么会崩溃吗?
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))
请注意,在迭代时修改 value(外部映射的)不会导致此异常。
它正在崩溃,因为您在隐式迭代树图时试图删除一个元素(因为它会影响内部迭代索引)。您应该将要删除的键保存在临时数据结构中,并在迭代树图后删除键。
使用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