为什么Iterator接口中没有add方法

时间:2012-06-25 20:07:32

标签: java collections iterator

Iterator Sun中添加了删除方法以删除最后访问的集合元素。为什么没有添加方法来向集合中添加新元素?它可能对集合或迭代器产生什么样的副作用?

7 个答案:

答案 0 :(得分:11)

好的,我们走了:

答案在设计常见问题中明确说明:

为什么不提供Iterator.add方法?

语义不清楚,因为迭代器的合同不能保证迭代的顺序。但请注意,ListIterator确实提供了一个add操作,因为它确保了迭代的顺序。

http://docs.oracle.com/javase/1.4.2/docs/guide/collections/designfaq.html#10

答案 1 :(得分:9)

迭代器的唯一目的是通过集合进行枚举。所有集合都包含add()方法以满足您的需求。添加到迭代器是没有意义的,因为可能会或可能不会对该集合进行排序(在HashSet的情况下)。

编辑:在处理其他问题时,我想出了Iterator缺少add()方法的另一个原因。在ArrayList(第111行)和HashMap(第149行)的引擎下,我们看到实现只是围绕对象数组的几种方法。现在我们考虑如何在内存中处理数组。

zero-based array indexes

这是一个包含5个元素的数组。但是,有六个指数。这个数组中的字母“a”被列为元素0,因为为了读取它,就像计算机那样从左到右读取,你必须从索引0开始。现在,如果我们遍历这个数组(是的,集合,但它归结为数组),我们将从索引0开始并继续索引1.在Iterator中的这一点,我们想要调用add("f");。在这一点上,让我们比较add()remove()的含义。 remove()会在数组中留一个空格,这很容易跳过,因为我们可以立即发现它不是成员。另一方面,add()会放入一个之前不存在的新元素。这将影响我们迭代的数组的长度。当我们到达最后一个元素时会发生什么?我们甚至可以保证它存在(即数组没有超过the maximum size)?

总而言之,这两种论据都有有效点,但最重要的是add()方法的行为在所有情况下都没有明确定义。 Sun必须选择限制功能的地方,并且他们选择不包含此方法。

答案 2 :(得分:5)

如果您正在使用列表,则可以使用ListIterator来提供添加和删除操作。

答案 3 :(得分:2)

我想再补充一点。

ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("aa");
arrayList.add("ab");
Iterator<String> iterator = arrayList.iterator();
while (iterator.hasNext()) {
    String string = (String) iterator.next();
}

这里迭代器最多需要最多 2 次迭代来完成它的迭代。 所以迭代器需要一定的时间在 N 时间内完成它的迭代。

但是如果我们添加 add() 方法会怎样:

while (iterator.hasNext()) {
    String string = (String) iterator.next();
    iterator.add("adding this data means iterator will always have next 
                    element.")
}

因此在迭代器中添加 add() 将有机会运行无限循环。 并且我们简单地使用迭代器遍历元素,以免陷入无限循环。

答案 4 :(得分:1)

Iterator只有一个指向下一个元素的指针。其中ListIterator也有指向前一个元素的指针(记住,它可以向后遍历)。

答案 5 :(得分:0)

我无法想到为什么add()无法包含在Iterator中的任何理论原因。正如Iterator可以允许从集合中删除元素本身一样,它可以设计为处理以相同方式添加的元素。

但我会说,在我用Java编程的这些年里 - 超过15年! - 我从未想过Iterator.add()方法。所以我怀疑它并不是那么有用。

答案 6 :(得分:0)

因为ListIterator保持插入顺序,所以您可以转到要添加的位置。 Iterator不在乎顺序,因此如果在迭代时将对象添加到过去的值中又会带来灾难,那该怎么办。这就是仅为迭代器提供remove()方法的原因,因为您有一个特定的对象和要删除的位置。