我有一个名为Graph的自定义类,我在其中使用邻接列表。更具体地说,我有一个哈希映射数组,其中每个哈希映射包含所有节点的邻居作为边。关键是结束节点,值是Edge对象。
现在我想让这个Graph类实现Iterable。有没有办法合并所有这些哈希映射并返回所有元素的公共迭代器?
使用该方法非常有效。
答案 0 :(得分:6)
您可以使用apache commons集合中的ChainedIterator
:
Iterator current = IteratorUtils.emptyIterator();
for(map: arrayOfHashmaps) {
current = IteratorUtils.chainedIterator(current, map.keySet().iterator);
}
如果你想避免公共收集,你可以只收集列表中的密钥集并迭代它:
List allKeys = new LinkedList();
for(map: arrayOfHashmaps) {
allKeys.addAll(map.KeySet());
}
return allKey.iterator();
第二种解决方案将使用更多的内存,并且会慢一点。但我怀疑这很重要。
答案 1 :(得分:1)
根据API HashMap有一个名为entrySet()的函数,它返回Hash中映射的set视图。集合是可迭代的对象。要创建Iterator,只需遍历数组,将每个哈希转换为一个集合,然后将各个迭代器组合成一个迭代器......
在java中没有内置的组合迭代器的方法,但编写自己的compose函数应该是微不足道的。
答案 2 :(得分:0)
我这样做的方法是创建一个实现Iterator的内部类。在内部,它跟踪1)当前索引到映射数组,以及2)当前映射中的迭代器。它的hasNext()
和next()
方法只会委托给当前的迭代器,或者如果迭代器完成,只需增加索引并更改迭代器。
答案 3 :(得分:0)
为什么不在各种地图上依次滚动自己的迭代?
public class MapCollection<K,V> implements Iterable<V> {
Map [] maps;
public Iterator<V> iterator(){
return new MapCollectionIterator(maps);
}
private class MapCollectionIterator<T>{
public boolean hasNext() {
public T next(){... (code omitted due to lazyness..)
}
}
答案 4 :(得分:0)
作为替代方案,您可以尝试在单个HashMap中存储图形的所有条目,其中密钥是包含节点编号和邻居节点编号的对象。我假设节点号通常是HashMaps数组的索引,而邻居节点是当前HashMap的键。这将使您能够执行与现在相同的检索,并迭代所有条目,而无需编写任何特殊代码。
不要忘记你需要为用作键的对象编写一个equals()和一个好的哈希函数(否则该对象可以非常简单)。如果您有非常大的图表,那么当然可能不合适。