我正在寻求迭代递归方法。
我有一个要迭代的对象列表,然后检查它们的子对象。
递归:
doFunction(Object)
while(iterator.hasNext())
{
//doStuff
doFunction(Object.subObjects);
}
我想把它改成这样
doFunction(Object)
iIterator = hashSet.iterator();
while(Iterator.hasNext()
{
//doStuff
hashSet.addAll(Object.subObjects);
}
对糟糕的伪代码感到抱歉,但基本上我想迭代子对象,同时将新对象附加到列表末尾进行检查。
我可以使用列表来完成此操作,并执行类似的操作
while(list.size() > 0)
{
//doStuff
list.addAll(Object.subObjects);
}
但我真的不想添加重复的子对象。 当然,我可以在添加之前检查 list.contains(each subObject) 是否存在。
但我很乐意使用 Set 来完成清洁工作。
那么基本上有没有办法在迭代集合时追加到集合中,或者是否有更简单的方法使列表像集合一样而不是手动检查 .contains()?
欢迎任何评论。
谢谢
最佳答案
我会使用两种数据结构——一个队列(例如 ArrayDeque
)用于存储要访问其子对象的对象,以及一个集合(例如 HashSet
)用于存储存储所有访问过的对象而不重复。
Set visited = new HashSet(); // all visited objects
Queue next = new ArrayDeque(); // objects whose subobjects are to be visited
// NOTE: At all times, the objects in "next" are contained in "visited"
// add the first object
visited.add(obj);
Object nextObject = obj;
while (nextObject != null)
{
// do stuff to nextObject
for (Object o : nextObject.subobjects)
{
boolean fresh = visited.add(o);
if (fresh)
{
next.add(o);
}
}
nextObject = next.poll(); // removes the next object to visit, null if empty
}
// Now, "visited" contains all the visited objects
注释:
-
ArrayDeque
是一个节省空间的队列。它是作为循环数组实现的,这意味着您使用的空间比添加元素时不断增长的List
少。 - “
boolean fresh =visited.add(o)
”结合了“boolean fresh = !visited.contains(o)
”和“if (fresh)”访问过.add(o)
”。
关于java - 在迭代java期间修改集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/497025/