Я изучаю интерфейс java iterator
и не могу понять, почему он так разработан.
Почему Java-итератор использует hasNext
и next
вместо того, чтобы объединить их в один метод?
это типичное использование java iterator
Iterator iter = //iterator from a list
while(iter.hasNext()){
Object obj = iter.next();
// do something to obj
}
почему бы и нет
Iterator iter = //iterator from a list
Object obj = null;
try {
while(true){
obj = iter.next();
// do something to obj
}
} catch (NoSuchElementException e) {}
Ясно, что этот подход выглядит некрасиво, но что произойдет, если next
вернет ноль, когда достигается конец, вместо того, чтобы генерировать исключение? чем код можно упростить до
Iterator iter = //iterator from a list
Object obj = null;
while((obj = iter.next()) != null){
// do something to obj
}
так работает NSEnumerator в Objective-C
NSEnumerator *enumerator = // from an array
while (id obj = [enumerator nextObject]) {
// do something to obj
}
Это увеличивает накладные расходы на установку навесного оборудования iterator
.
Это также делает итератор Java не поточно-ориентированным. Например, ArrayList содержит один элемент. Оба потока одновременно запрашивают один итератор для этого списка hasNext
. Тогда оба потока увидят true
и вызовут next
на этом итераторе. Потому что есть только один элемент, и итератор был задан дважды, что определенно приведет к состоянию исключения или ошибки.
Я знаю, что существует поточно-ориентированный итератор, но я не уверен, что он реализован, но я думаю, что происходит много блокировок, которые делают его неэффективным.
Я думаю, что проблема в том, что проверка и обновление не происходят атомарно, и я не могу понять, почему Java iterator
разработал такой интерфейс.
Обновление
Я вижу, что null может быть значением, поэтому мой подход неверен. Но можно ли обойти проблемы, о которых я говорил выше?