我现在遇到了一个令人不爽的问题。假设有一个对象列表 aList (其类型称为 Object),我想要迭代它。基本上,代码应该像这样:
for(int i = 0; i < aList.Size(); ++i)
{
aList[i].DoSth();
}
这里的难点在于,DoSth() 方法可能会改变调用者在列表中的位置!因此,可能会出现两种结果:第一,迭代可能永远无法结束;第二,可能会跳过某些元素(迭代并不一定像上面那样,因为它可能是一个链表)。当然,第一种情况是主要问题。
必须在以下约束条件下解决该问题:
1)不能排除进行位置交换操作的可能性;
2)如果需要且可行,可以将位置交换操作延迟到迭代完成后进行;
3)由于经常发生,因此只能最小程度地修改迭代(因此不建议执行创建列表副本等操作)。
我使用的语言是C++,但我认为在JAVA和C#等语言中也存在类似的问题。
以下是我尝试过的方法:
a)尝试禁止在迭代过程中进行位置交换操作。但是,这涉及太多客户端代码文件,找到并修改所有这些文件实际上是不可行的。
b)修改每个可以直接或间接被DoSth() 调用的Object 的单个方法(例如Method()),以以下方式进行修改:首先我们可以知道正在进行迭代的是aList,并且我们将相应地处理Method()。如果迭代正在进行中,则我们将延迟Method()想要执行的操作;否则,它立即执行想要的操作。问题在于:如何最好地(易于使用且足够高效)延迟此处的函数调用?Method()的参数可能相当复杂。此外,这种方法还涉及相当多的函数!
c)尝试修改迭代过程。我在这里遇到的实际情况非常复杂,因为它涉及两层迭代:第一层是简单的数组迭代,而第二层是递归函数中的典型链接列表迭代。对于现在的第二层迭代,我能做的最好的事情是限制它的迭代次数并防止同一个元素被迭代多次。
因此,我想可能有更好的方法来解决这个问题吗?也许一些优秀的数据结构会有所帮助?
vector
时,这非常容易实现。 - Some programmer dudeDoSth
能否被修改以返回新位置? - Angew is no longer proud of SO