Итераторы в редукторе не так просты, как вы думаете.
Проблема в том, что общее количество элементов, которые вы перебираете, может не помещаться в памяти.Это означает, что итератор может читать с диска.Если у вас есть две независимые копии итератора, то одна из них может быть намного впереди другой, что означает, что данные, между которыми указывают точки двух итераторов, не могут быть отброшены.
Для простоты реализации,Hadoop не поддерживает наличие более одного итератора для значений приведения.
Практическое влияние этого состоит в том, что вы не можете пройти один и тот же итератор дважды.Это не хорошо, но это так.Если вы точно знаете, что количество элементов поместится в память, вы можете скопировать все элементы в список, как это предложено MrGomez.Если вы этого не знаете, возможно, вам придется использовать вторичное хранилище.
Лучшим подходом является перепроектирование вашей программы, чтобы вам не требовалось неограниченное хранилище в редукторе.Это может быть немного сложнее, но есть стандартные подходы к проблеме.
Для вашей конкретной задачи у вас есть квадратичный рост размера выхода по сравнению с наибольшим входным набором сокращения.Обычно это действительно плохая идея.В большинстве случаев вам не нужны ВСЕ пары, только самые важные пары.Если вы можете каким-то образом обрезать набор пар, то все готово, и вы сможете удалить ограничение всех пар.
Например, если вы пытаетесь найти 100 пар с наибольшимсуммой для каждого набора сокращений вы можете сохранить приоритетную очередь с 100 самыми большими входными данными, замеченными до сих пор, и приоритетную очередь с 100 самыми большими суммами, замеченными до сих пор.Для каждого нового ввода вы можете сформировать сумму с самыми большими 100 числами, которые когда-либо видели, и попытаться вставить эти суммы во вторую очередь.Наконец, вы должны вставить новый ввод в первую очередь и обрезать обе очереди до 100 элементов, удалив наименьшие значения (при необходимости).В методе close при редуцировании вы должны сбросить очередь с приоритетами.Этот подход гарантирует, что вам нужно только минимум (n ^ 2, 200) элементов хранилища, что позволяет избежать проблемы n ^ 2 и избежать двойного прохода через вход, сохраняя 100 самых больших видимых элементов, а не все видимые элементы.