在迭代java期间修改集合

She*_*oss 2 java iterator hashset

我正在寻找迭代的递归方法.

我有一个我想要迭代的对象列表,然后检查它们的子对象.

递归:

doFunction(Object)
while(iterator.hasNext())
{
   //doStuff
   doFunction(Object.subObjects);
}
Run Code Online (Sandbox Code Playgroud)

我想把它改成这样的东西

doFunction(Object)
iIterator = hashSet.iterator();
while(Iterator.hasNext()
{
   //doStuff
   hashSet.addAll(Object.subObjects);
}
Run Code Online (Sandbox Code Playgroud)

抱歉可怜的伪代码,但基本上我想迭代子对象,同时将新对象附加到列表末尾进行检查.

我可以使用列表执行此操作,并执行类似的操作

while(list.size() > 0)
{
   //doStuff
   list.addAll(Object.subObjects);
}
Run Code Online (Sandbox Code Playgroud)

但我真的不想添加重复的子对象.当然我可以在添加它之前检查list.contains(每个subObject)是否正确.

但我很想用套装去完成那个清洁工.

所以基本上是在迭代它时附加到一个集合,或者是否有更简单的方法使List像集合一样而不是手动检查.contains()?

任何评论都表示赞赏.

谢谢

Zac*_*ena 5

我将使用两个数据结构---一个队列(例如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
Run Code Online (Sandbox Code Playgroud)

笔记:

  • ArrayDeque是一个节省空间的队列.它实现为循环数组,这意味着您List在添加元素时使用的空间少于保持增长的空间.
  • " boolean fresh = visited.add(o)"结合" boolean fresh = !visited.contains(o)"和" if (fresh) visited.add(o)".