在Iterator
Sun中添加了删除方法以删除最后访问的集合元素。为什么没有添加方法来向集合中添加新元素?它可能对集合或迭代器产生什么样的副作用?
答案 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行)的引擎下,我们看到实现只是围绕对象数组的几种方法。现在我们考虑如何在内存中处理数组。
这是一个包含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()方法的原因,因为您有一个特定的对象和要删除的位置。