Java: Копировать коллекцию с использованием Iterator
У меня есть метод, который в качестве аргумента имеет итератор для коллекции. Внутри метода я хочу скопировать коллекцию, на которую итератор "указывает". Однако только последняя запись коллекции присутствует в копии коллекции, она присутствует N раз, где N - размер оригинальной коллекции.
public void someMethod(Iterator<Node> values) {
Vector<Node> centralNodeNeighbourhood = new Vector<Node>();
while (values.hasNext()) {
Node tmp = values.next();
centralNodeNeighbourhood.add(tmp);
}
...
//store the centralNodeNeighbourhood on disk
}
Пример "Оригинальная коллекция":
1
2
3
Пример "СентралНод Neighbourhood Collection":
3
3
3
Может ли кто-нибудь указать мне на мою ошибку? Я не могу изменить аргументы метода, я только получаю Iterator в коллекцию, ничего не могу с этим поделать.
ОБНОВЛЕНИЕ (Ответ на несколько вопросов)
while (values.hasNext()) {
Node tmp = values.next();
System.out.print("Adding = "+tmp.toString());
centralNodeNeighbourhood.add(tmp);
}
Печатает правильные оригинальные элементы коллекции. Я не знаю, какой тип является исходной коллекцией, но Iterator из std java. Метод является
public class GatherNodeNeighboursInfoReducer extends MapReduceBase
implements Reducer<IntWritable, Node, NullWritable, NodeNeighbourhood>{
public void reduce(IntWritable key, Iterator<Node> values,
OutputCollector<NullWritable, NodeNeighbourhood> output, Reporter reporter) throws IOException {...}
}
метод из старых Hadoop API (Hadoop версия 0.20.203.0)
РЕШЕНО Я делал копию объекта tmp на каждой итерации и добавляю эту копию в коллекцию centralNodeNeighbourhood. Это решило мою проблему. Спасибо за вашу (быструю) помощь.
2 ответа
Похоже, что Итератор каждый раз возвращает один и тот же объект Node. Если это так, вам нужно взять копию узла, прежде чем добавить его в коллекцию. (В противном случае вы будете добавлять один и тот же объект каждый раз, и он будет иметь последние установленные значения)
Метод Reduce Hadoop указывает, что он использует объекты-значения в своем итераторе. Это ужасная вещь, но это то, что она делает.
Фреймворк будет повторно использовать объекты ключа и значения, которые передаются в Reduce, поэтому приложение должно клонировать объекты, копии которых они хотят сохранить. Во многих случаях все значения объединяются в ноль или одно значение.