[详细] HashMap在迭代时删除了更多项目(不是您正在访问的项目)?

时间:2012-01-21 01:16:24

标签: java graph

我想使用邻接列表将法线图转换为星形图。

我的想法是使用HashMap< Interger,ArrayList<整数>>存储点及其邻接列表。假设,我们有

1- {2}; 2- {3,4} 3- {2,4} 5- {6} 6- {5} =>结果我想要1- {2,3,4} 5- {6}

我迭代了hashmap和相关的arraylist。如果hashmap的arraylist的迭代项是进一步hashmap项的关键。我根据某些条件从另一个hashmap项中减去arraylist项,然后删除这个进一步的hashmap项以避免循环它们。

但是,循环时不允许使用hashmap迭代器删除其他项。说真的,我不想将删除的项目存储在另一个列表中并再次迭代它们以删除这些项目,如果我的数据集相当大,那就太贵了。

因此,感谢有关迭代问题或数据结构的建议。

import java.util.*;
import org.apache.commons.collections.CollectionUtils;;


public class StarFind {


    public static void main(String[] args) {

        Map<Integer, ArrayList<Integer>> map = new HashMap<Integer, ArrayList<Integer>>() ;
        // contents of the map: <1,[2,4]>  <2,[1,4]>  <3,[1,2,4]>  <5,[6]><6,[5]>

        Map< Integer, ArrayList<Integer>> copyMap = new HashMap<Integer, ArrayList<Integer>>(map);      
        Iterator<Map.Entry<Integer, ArrayList<Integer>>> entries = map.entrySet().iterator();

        while (entries.hasNext()) { //problem here: when iterating 1th, the 2nd is removed from the hashmap and entries.next() is still the deleted 2nd item.
            Map.Entry<Integer, ArrayList<Integer>> entry = entries.next();
            ArrayList<Integer> alTemp = entry.getValue();

            for (int i=0; i<alTemp.size();i++)
            {
                int valueItem= alTemp.get(i);
                if (copyMap.containsKey(valueItem))
                {
                    @SuppressWarnings("unchecked")
                    Collection<Integer> tempCollection =  CollectionUtils.subtract(copyMap.get(valueItem), entry.getValue());
                    tempCollection.remove(entry.getKey());
                    entry.getValue().addAll(tempCollection);
                    copyMap.remove(valueItem);
                    map.remove(valueItem);
                }
            }
        }

}
}

2 个答案:

答案 0 :(得分:0)

您可以尝试将值设置为sentinal值(通常为null),然后在第二次传递中进行清理,而不是在执行时删除。

答案 1 :(得分:0)

我自己喜欢哨兵价值解决方案,但这是另一种选择:

您可以为地图中的键定义逻辑排序(例如顶点id)。然后,通过使用SortedMap或带有键值的单独排序数据结构,您现在可以立即删除项目,仍然可以在O(log(n))中找到下一个项目。您可以使用SortedSet,或者只是使用简单的List并使用Collections.sort()。