What is the concept of java iterator?

I am researching the java iterator interface and cannot understand why it is created this way.

Why hasNext Java iterator use hasNext and next instead of combining them into one method?

this is a typical use of the java iterator

 Iterator iter = //iterator from a list while(iter.hasNext()){ Object obj = iter.next(); // do something to obj } 

why not

 Iterator iter = //iterator from a list Object obj = null; try { while(true){ obj = iter.next(); // do something to obj } } catch (NoSuchElementException e) {} 

Clearly this approach looks ugly, but what happens if next returns null when the reach ends, throwing an exception instead? how code can be simplified to

 Iterator iter = //iterator from a list Object obj = null; while((obj = iter.next()) != null){ // do something to obj } 

this is how NSEnumerator works in Objective-C

 NSEnumerator *enumerator = // from an array while (id obj = [enumerator nextObject]) { // do something to obj } 

This increases the overhead of implementing a custom iterator .

It also makes the Java iterator not thread safe. For example, ArrayList has one element. Two threads simultaneously request the same iterator for this hasNext list. Then both threads will see true , and they will call next on this iterator. Because there is only one element, and the iterator is set twice, which will definitely lead to an exception or error.

I know there is a thread-safe iterator, but I'm not sure if it is being implemented, but I think there are many locks that make it inefficient.

I think the problem is that validation and updating do not happen due to atomicity, and I don’t understand why Java developed the iterator interface.


Update

I see that null can be a value, so my approach is not valid. But is there any possible workaround for the problems that I mentioned above?

+4
source share
3 answers

Your suggestion would make it impossible to have null values ​​in collections, as it uses null as a "poison pill" to detect the end of the iteration.

In very rare cases, two threads share an iterator, you just need to wrap it in some user class and synchronize access to the iterator to make the check-then-act operation atomic. This is necessary in any case, even if the iterator had only one method, the support collection (ArrayList in your example) is not thread safe.

+7
source

Your first suggestion is poor design because it relies on throwing and catching an exception for the condition that is known to ultimately happen. Exceptions are quite expensive and are intended only for “exceptional” situations that usually should not occur.

Your second sentence does not take into account that Iterable can have null elements.

As for the thread safety bit, the standard Iterator does not have to be thread safe, and a special implementation with added overhead is required. This is true for most Java structures. As JB Nizet points out, the issue of Iterable structure is thread safe before its Iterator .

+4
source

To improve the clarity of the source code, use (example with a collection of strings)

 Iterable<String> values = ... // typically a Collection (List, Set...) for (String value : values) { // do something with the value } 

I agree with the previous answers about zero-bound collections, loop control with exceptions (which is a brutal form), and thread safety.

Of your suggestions, the null restriction of the collection is the least unreasonable, especially if your code has a no-zero policy. However, it is very uniomatic Java (edits and breaks the contract of the Iterator interface), so it can confuse future maintainers of the code (edit: and possibly cause subtle and / or unexpected errors).

+2
source

Source: https://habr.com/ru/post/1399350/


All Articles