-2

I was learning the java Collection framework from a tutorial, it was saying Iterator Interface HAS-A relationship with Collection Interface, which gives the Collection classes the feature to be forward traversed. And ListIterable Interface which is a child interface of Iterator Interface has a HAS-A relation with List Interface and gives a backward traversing feature to list classes only.

If Someone can kindly explain how the HAS-A relationship is working between the Interfaces or I am learning something wrong? Thank you.

  • 1
    I don’t know why this question is received so badly. It is not a duplicate of a generic “What is the difference between ‘IS -A’ relationship and ‘HAS-A’ relationship in Java?” question. This question is specifically about interfaces and the Collection API. – Holger Sep 05 '22 at 10:37

1 Answers1

1

The statement of about this interface relationship is an oversimplification.

The has-a relationship is established between the implementing classes. If interfaces are designed in a way, that all implementing classes always establish a has-a relationship, we can say that there is a has-a relationship between the interfaces.

In case of the Iterator interface, this is not always the case.

An interface could establish an always existing has-a relationship by declaring at least one method depending on the other object, for example an accessor method. It still can’t enforce implementation classes to implement it in the intended way. E.g. an implementation could implement this method by always throwing an exception. But if an interface’s contract implies a has-a relationship, we may ignore violating implementations.

In case of the Iterator interface, there is no accessor method but a remove() method supposed to affect the source collection. But this method has been marked as optional operation and is explicitly allowed to throw an UnsupportedOperationException. So while it is typical for an iterator implementation to a have a has-a relationship to a collection it was created for, this is not always the case.

A counter-example would be CopyOnWriteArrayList. When you call iterator() on it, the returned iterator will have a has-a relationship to the underlying array. So at the iterator’s creation time, both, the collection and the iterator, have a has-a relationship to that array, but when you modify the collection, it will establish a has-a relationship to a new array, so after the modification, the iterator and the collection are entirely decoupled.

Also, not every iterator originates from a collection. For example

Iterator<String> i = Collections.emptyIterator();
Iterator<Integer> i = IntStream.range(0, 10).iterator();

See Collections.emptyIterator() and BaseStream.iterator().

Note that for some cases, most notably immutable collections, we may say that the iterators conceptually have a has-a relationship to the collections because they provide access to their contents, even if implemented in a different way. That’s why the examples above are carefully chosen to counter the statement on a conceptual level, either because there is no collection or the collection is explicitly documented to become decoupled from the iterators on modifications.

Holger
  • 285,553
  • 42
  • 434
  • 765