Вопрос

Лично я нахожу набор функциональных возможностей, предоставляемых java.util.Iterator довольно жалким.Как минимум, я хотел бы иметь такие методы, как:

  • peek() возвращает следующий элемент без перемещения итератора вперед
  • previous() возвращает предыдущий элемент

Хотя есть много других возможностей, таких как first() и last().

Кто-нибудь знает, существует ли такой сторонний итератор?Вероятно, его нужно было бы реализовать как декоратор java.util.Итератор, чтобы он мог работать с существующими коллекциями java.В идеале, он должен быть "осведомлен о дженериках".

Заранее спасибо, Дон

Это было полезно?

Другие советы

Вы можете получить previous() легко, просто используя java.util.ListIterator.

Заглянуть в этот момент легко, выполнив

public <T> T peek(ListIterator<T> iter) throws NoSuchElementException {
    T obj = iter.next();
    iter.previous();
    return obj;
}

К сожалению, будет проще использовать его в качестве служебного метода, поскольку каждый класс коллекции реализует свои собственные итераторы.Создать оболочку для получения метода peek для каждой коллекции в некотором интерфейсе, таком как MyListIterator было бы довольно много работы.

Я думаю, причина, по которой они не реализованы, заключается в том, что они нетривиальны для некоторых коллекций и оказали бы большое влияние на производительность.Я думаю, для вас было бы довольно просто заставить это работать для коллекций, которые вам небезразличны.

Мне также не нравится, что итераторы Java не имеют способа получить текущее значение без его перемещения (и поэтому вы не можете легко написать код, который ветвится на основе значения, просто передавая итератор - вы также должны передать значение, которое у вас теперь есть).

Есть чертовски веская причина, по которой универсальные операторы не реализуют эти функции:они существуют не для всех контейнеров.Типичным примером является контейнер, представляющий некоторые внешние входные данные, например файл, рассматриваемый как поток.Каждый раз, когда вы читаете значение, вы потреблять это и переместите указатель вперед, хотите вы этого или нет.Если вы накладываете эти ограничения на универсальные итераторы, то вы теряете универсальность итераторов.

Если вы хотите previous метод, как было предложено, используйте ListIterator<>, который затем ограничивается контейнером, ведущим себя как списки.

Одна вещь, на которую я бы обратил внимание, - это реализация Seq в clojure

http://clojure.org/sequences

Реализация базовых классов выполнена на Java, и доступен полный исходный код.Seqs - это декораторы для java-итераторов (берут и реализуют интерфейсы java-итератора), но они также предоставляют свой собственный интерфейс, который может быть больше того, что вы хотите, - или, по крайней мере, отправной точкой.

Как предположил юкаганович, возможно, вы захотите ознакомиться с google-коллекции всякое такое.Определенно, есть некоторая поддержка для некоторых вещей, которые вы хотите, таких как подглядывающий.Кроме того, как упоминали некоторые другие, реализация всех этих функций для всех коллекций может быть опасной с точки зрения возможностей или производительности.

public class Iterazor<T> {
  private Iterator<T> it;
  public T top;
  public Iterazor(Collection<T> co) {
    this.it = co.iterator(); 
    top = it.hasNext()? it.next(): null; 
  }
  public void advance() { 
    top = it.hasNext()? it.next(): null; 
  }
}

// usage

for(Iterazor<MyObject> iz = new Iterazor<MyObject>(MyCollection); 
    iz.top!=null; iz.advance())
  iz.top.doStuff();
}

Я видел, что кто-то ссылался на коллекции Google, но никто не упомянул, что метод, который вы ищете, называется Iterators.peekingIterator().

Тем не менее, было бы лучше, если бы вы могли просто использовать ListIterator.

Я никогда не сталкивался с проблемой, когда мне нужно было заглянуть ();Итератор работал у меня просто отлично.Мне любопытно, как вы используете итераторы, которые, по вашему мнению, нуждаются в этой дополнительной функциональности.

Похоже, вам, возможно, было бы лучше использовать стек.

Коллекции Java были написаны так, чтобы обеспечить минимальный набор полезной функциональности.Это очень хороший подход к коду, который имеет должен быть реализован любым, кто реализует Java.Раздувание интерфейса с функциональностью, которая мог бы быть полезным может привести к значительному увеличению объема кода, при этом улучшения заметят лишь немногие.Если peek() и previous() были частью стандартного итератора, это означает, что все пишут новый вид коллекции должен реализуйте это, независимо от того, разумно это или нет.

Итераторы также предназначены для работы с вещами, которые физически не может вернитесь назад, сделав невозможными функции peek() и previous().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top