Когда расширенный цикл цикла (цикл 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
}
Я теряю преимущества цикла for-each. Это не только нажатия клавиш. Мне не нравится выставлять итератор, если мне это не нужно, так как легко совершить ошибку при вызове 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-loop не смог просто принять Iterator
? Это, вероятно, будет иметь большое значение для того, чтобы заставить меня жить с нынешним дизайном.