2011-11-29 3 views
1

У меня есть метод, который в качестве аргумента имеет итератор для коллекции. Внутри метода я хочу скопировать коллекцию, итератор «указывает на». Однако в копии коллекции присутствует только последняя запись коллекции, она присутствует N раз, где N - размер оригинальной коллекции.Java: копирование коллекции с использованием Iterator

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 

Воплощение "Коллекция centralNodeNeighbourhood":

3 
3 
3 

Может кто-то момент мне мою ошибку? Я не могу изменить метод args, я получаю только Итератор в коллекции, ничего не могу с этим поделать.

UPDATE (ответ на вопросы)

while (values.hasNext()) { 
      Node tmp = values.next(); 
      System.out.print("Adding = "+tmp.toString()); 
      centralNodeNeighbourhood.add(tmp); 
     } 

Печатает собственные оригинальные элементы коллекции. Я не знаю, какой тип является исходной коллекцией, но Итератор - из 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. Это решило мою проблему. Thx для всей вашей (быстрой) помощи.

+0

Если вы сбрасываете 'tmp' в этом цикле, оно показывает, что вы ожидаете? –

+1

Как работает данный итератор, он специфичен для реализации для класса, который его предоставляет; Таким образом, класс, предоставляющий вам итератор, вполне может иметь ошибку в их дизайне. Эта коллекция, которую вы даете ей, является частью стандартной библиотеки java, или она создана пользователем? – djhaskin987

+0

Проверьте, если вы получаете тот же экземпляр с оператором ==. Скажите нам результат теста. – Puce

ответ

3

Кажется, что Итератор каждый раз возвращает один и тот же объект узла. Если это так, вам нужно взять копию узла перед добавлением его в коллекцию. (В противном случае вы будете добавлять один и тот же объект каждый раз, и он будет иметь последние значения, на которые он был установлен)

+2

А? Я действительно не понимаю, что вы предлагаете в качестве исправления, но если «Итератор» сломан, вы ввернуты, не так ли? – erickson

+2

Некоторые итераторы возвращают один и тот же объект каждый раз. то есть каждый раз, когда вы вызываете values.next(), вы фактически получаете один и тот же объект (устанавливаете на разные значения). Обычно считается путаница, но легальная. –

+0

Вот пример коллекции, чей итератор entrySet() возвращает один и тот же объект в Next() каждый раз. Http: //tech.puredanger.com/2009/06/11/collections-puzzler/ –

1

Метод Hadoop reduce указывает, что он повторно использует объекты значения в своем итераторе. Это ужасно, но это так.

Структура будет повторно использовать объекты ключа и значения, которые передаются в сокращение, поэтому приложение должно клонировать объекты, которые они хотят сохранить. Во многих случаях все значения объединяются в ноль или одно значение.

Смежные вопросы