23

In Iterator Sun added the remove method to remove the last accessed element of the collection. Why there is no add method to add a new element to the collection? What kind of side-effects it may have to the collection or iterator?

fastcodejava
  • 39,895
  • 28
  • 133
  • 186
droidsites
  • 1,035
  • 4
  • 16
  • 29

7 Answers7

13

Okay, here we go:

The answer is clearly stated in the design faq:

Why don't you provide an Iterator.add method?

The semantics are unclear, given that the contract for Iterator makes no guarantees about the order of iteration. Note, however, that ListIterator does provide an add operation, as it does guarantee the order of the iteration.

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

jontro
  • 10,241
  • 6
  • 46
  • 71
  • Sorry for being late to answer. But for example LinkedHashSet does maintain insertion order. Why didn't they make Iterator for it then? `Add()` method in that case would work fine, right? – Stefan Sep 28 '20 at 02:52
  • @Stefan read this question: https://stackoverflow.com/questions/26277042/no-listiterator-in-linkedhashmap-and-linkedhashset which covers that case – jontro Sep 28 '20 at 22:47
11

The sole purpose of an Iterator is to enumerate through a collection. All collections contain the add() method to serve your purpose. There would be no point in adding to an Iterator because the collection may or may not be ordered (in the case of a HashSet).

EDIT: While working on another problem, I came up with another reason that Iterator lacks an add() method. Looking under the hood of ArrayList (line 111), and HashMap (line 149), we see that the implementation is just a few methods surrounding an array of objects. Now we consider how arrays are treated in memory.

zero-based array indexes

This is an array of 5 elements. However, there are six indices. The letter "a" in this array is listed as element 0 because in order to read it, left to right like a computer does, you have to start at index 0. Now, if we are iterating through this array (yes, collection, but it boils down to an array), we will start at index 0 and continue to index 1. At this point in the Iterator, we want to call add("f");. At this point, let's compare the implications of add() and remove(). remove() would leave a space in the array, which is easy to jump over, because we can immediately recognize that it isn't a member. On the other hand, add() would put a new element in which wasn't there before. This will affect the length of the array that we're iterating through. What happens when we get to that last element? Can we even guarantee that it is there (that is, that the array hasn't exceeded the maximum size)?

All in all, the arguments one way or another both have valid points, but the bottom line is that the behavior of an add() method is not well defined in all cases. Sun had to make a choice where to limit functionality, and they chose not to include this method.

Community
  • 1
  • 1
gobernador
  • 5,659
  • 3
  • 32
  • 51
  • "because the collection may or may not be ordered" - do you please elaborate it a little. Thanks – droidsites Jun 25 '12 at 20:24
  • I got your statement :-) . Thanks – droidsites Jun 25 '12 at 20:42
  • 1
    A HashSet gives no guarantee for the order of its members. If you are iterating through it to try to find a point at which to insert a value, you've just defeated the point of an Iterator. – gobernador Jun 25 '12 at 20:43
  • 2
    But then there wouldn't be a point in removing from an `Iterator` either. Yet `remove()` exists to make it (optionally) possible to remove elements without invalidating the `Iterator`. Shouldn't `add(E)` exist to make it possible to add elements without invalidating the `Iterator`? Of course you can add elements to the `Iterable` after the iteration. But the same goes for removal of elements. I think `Iterator` has a `remove()` method because generally it's efficient, easy to implement and defined clearly in contrast to `add(T)`. – Robert Jun 26 '12 at 03:42
  • @Robert It's a shaky argument, I admit, but I agree with your last sentence. As jontro links in his (second) answer, the design FAQ doesn't even give a good explanation. I believe a `remove()` method has more of a place in an `Iterator` than an `add(T)` method. The bottom line is that, for some reason, Sun chose to limit an `Iterator`'s capabilities at that particular point. – gobernador Jun 27 '12 at 01:51
  • But then ListIterator has add method. Then these points goes same for listiterator as well – Deca Jul 28 '18 at 10:14
5

If you are working on a list you could use ListIterator which provides both add and remove operations.

jontro
  • 10,241
  • 6
  • 46
  • 71
  • 5
    Doesn't answer the question actually. But yes, `Iterator` doesn't implement `add` because it's not `ListIterator`. – Robert Jun 25 '12 at 20:23
2

I would like to add one more point.

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();
}

Here the iterator takes max to max 2 iterations to complete it's iteration. So the iterator will take a definite time to complete it's iteration in N time.

But what if we add the add() method:

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

So adding add() in the iterator will have a chance to run an infinite loop. And simply we use iterator to traverse over the element, to not get in an infinite loop.

Josef
  • 2,869
  • 2
  • 22
  • 23
1

Iterator have a pointer to the next element only. where as ListIterator have pointers to the previous element also(remember, it can traverse backwards).

Vincent Lal
  • 103
  • 1
1

Because ListIterator maintains the insertion order and so you can get to a point where you want to add. Iterator doesn't care about order and so what if it adds the object in past values while iterating than that would be a disaster. That's the reason iterator is only given remove() method because you have a particular object and place from where to remove.

dev work
  • 11
  • 1
0

I cannot think of any theoretical reason why add() could not have been included in Iterator. Just as the Iterator can allow for elements being removed from the collection through itself, it could be designed to handle elements being added in the same way.

But I will say that in all my years of programming in Java -- over 15! -- I have never wanted an Iterator.add() method. So I suspect it's simply not all that useful.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186