Странное поведение итераторов Java

Я столкнулся со странной проблемой при использовании итераторов Java.

В определенной функции я получаю итерируемый объект с именем filelist, и я выполняю следующее:

System.out.println("First iteration:");
for(Text t : filelist) System.out.println(t);
System.out.println("Second iteration:");
for(Text t : filelist) System.out.println(t);

и вывод:

First iteration:

file2.txt

file1.txt

file1.txt

Second iteration:

filelist относится к типу Iterable<Text>. Я работаю с фреймворком Hadoop map/reduce.

Итак, мой вопрос: почему список файлов пуст во втором цикле, если я не изменил его в первом?


person Caesar23    schedule 16.01.2016    source источник
comment
Какой тип filelist?   -  person Tunaki    schedule 16.01.2016
comment
Итерируемый‹Текст›. Я работаю с каркасом карты/уменьшения Hadoop.   -  person Caesar23    schedule 16.01.2016
comment
Этот код используется в классе редуктора, поэтому, поскольку я использую структуру Hadoop, я предполагаю, что каждый редуктор получает объект List‹Text›. Правильно ?   -  person Caesar23    schedule 16.01.2016
comment
Список также является интерфейсом. Добавьте System.out.println(filelist.getClass().getName()); и расскажите, что получилось. Тем не менее, каким бы ни был тип, если базовая структура данных не изменяется одновременно, этого никогда не должно происходить.   -  person JB Nizet    schedule 16.01.2016
comment
Возвращаемое значение: org.apache.hadoop.mapreduce.task.ReduceContextImpl$ValueIterable   -  person Caesar23    schedule 16.01.2016
comment
Пожалуйста, не добавляйте ответ в свой вопрос. Если приведенный ниже ответ касается вашей проблемы, вы должны принять его вместо этого.   -  person Makoto    schedule 16.01.2016


Ответы (1)


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

List<Text> myList = new ArrayList(filelist)
person Dzmitry Paulenka    schedule 16.01.2016
comment
Вы имеете в виду Iterable, а не Iterator. Iterator никогда не повторяется. Это правда, что в документе Iterable ничего не упоминается, но я никогда не видел ни одного Iterable, который можно повторить только один раз. Это должен быть Iterator или Stream, а не Iterable. - person JB Nizet; 16.01.2016
comment
Тем не менее Iterable просто возвращает итератор. Итак, я имел в виду, что этот интерфейс не требует Iterable, чтобы каждый вызов iterator() возвращал новый и готовый экземпляр. Итерируемый только allows an object to be the target of the "foreach" statement - person Dzmitry Paulenka; 16.01.2016