Идиоматический способ использования для каждого цикла с учетом итератора?
Когда расширенный цикл for (цикл foreach) был добавлен в Java, он был настроен для работы с целевым объектом массива илиIterable
.
for ( T item : /*T[] or Iterable<? extends T>*/ ) {
//use item
}
Это прекрасно работает для классов Collection, которые реализуют только один тип итерации и, таким образом, имеют одинiterator()
метод.
Но я нахожусь невероятно расстроенным из-за того, что я хочу использовать нестандартный итератор из класса Collection. Например, я недавно пытался помочь кому-то использоватьDeque
как LIFO / стек, но затем печатать элементы в порядке FIFO. Я был вынужден сделать это:
for (Iterator<T> it = myDeque.descendingIterator(); it.hasNext(); ) {
T item = it.next();
//use item
}
Я теряю преимущества для каждого цикла. Это не просто нажатия клавиш. Мне не нравится выставлять итератор, если мне не нужно, так как легко ошибиться, вызвавit.next()
дважды и т. д.
Теперь в идеале я думаю, что цикл для каждого должен был принятьIterator
также. Но это не так. Так есть ли идиоматический способ использования цикла for-each в этих обстоятельствах? Я также хотел бы услышать предложения, которые используют библиотеки общих коллекций, такие как Guava.
Лучшее, что я могу придумать в отсутствие вспомогательного метода / класса:
for ( T item : new Iterable<T>() { public Iterator<T> iterator() { return myDeque.descendingIterator(); } } ) {
//use item
}
Который не стоит использовать.
Я бы хотел увидеть что-то подобное в ГуавеIterables.wrap
чтобы сделать это идиоматическим, но ничего подобного не нашел. Очевидно, что я мог бы свернуть свою собственную обертку Iterator через метод класса или вспомогательный метод. Есть другие идеи?
Редактировать: Как примечание, может ли кто-нибудь дать вескую причину того, почему расширенный цикл for не мог просто принятьIterator
? Это, вероятно, во многом помогло бы мне жить с нынешним дизайном.