Random Tech Thoughts

The title above is not random

内部迭代器的限制

内部迭代器确实很方便,但是它也有一些限制。

一个是内部迭代器只能作用在容器的数据上,而不能作用于容器本身。以 Java 为例来说,你想将容器中满足某些条件的成员从容器中除去,如果你使用外部迭代器那么很简单只要在迭代到满足条件的成员时调用 Iterator 的 remove 方法。但如果你使用增强的 for 循环,因为你操作的是数据,所以你没用办法直接把它从原来的容器中除去。

对于这种情况其实还是很好解决的,只要创建一个新的容器,然后把需要的成员添加到这个容器里就可以了。这样这个新的容器中包含的就是“过滤”出来的成员,把原来的容器赋值为这个新的容器就起到剔出某些成员的目的了。由于容器里存放的都是引用而不是新创建对象,所以这里增加的开销并不会很大。

其实这种方式在 Scheme 中一直都在使用。通用的思想是一个“过滤器”接受一个输入序列,输出一个过滤过的序列。拿上一篇 “ Callback 与内部迭代器” 的文章里的 Scheme 的例子来看,给 map 过程不同的过程为参数实际上就构造出了不同的过滤器,items 就是过滤器的输入,而 map 过程的返回值就是过滤过的序列。由于 Scheme 的每一个函数都有返回值在加上 Scheme 使用序列作为通用的数据结构,过滤器的思想在 Scheme 中用起来非常顺畅,不像 Java 一样要另外创建一个容器,还要将原来的容器赋值为新的容器。

第二个限制是要同时遍历多个容器时用内部迭代器无法做到。(至少我没用想到有什么办法。)Ruby 虽然大量使用内部迭代器,但是它可以通过 Generator 来得到外部迭代器,这样在需要同时遍历多个容器的时候会非常有用。

Comments