Может ли коллекция иметь несколько итераторов в Java? - PullRequest
5 голосов
/ 15 марта 2011

Можно ли иметь несколько итераторов в одной коллекции и каждый из них отслеживает независимо?Предполагается, что после назначения итераторов не удаляются и не вставляются.

Ответы [ 5 ]

13 голосов
/ 15 марта 2011

Да.

Иногда действительно раздражает, что ответы должны состоять из 30 символов.

7 голосов
/ 15 марта 2011

Да, это возможно.Это одна из причин, по которой они являются итераторами, а не просто методами коллекции.

Например, List итераторы (определенные в AbstractList) содержат int для текущего индекса (для итератора).Если вы создадите несколько итераторов и вызовете next() разное количество раз, у каждого из них будет свой int cursor с другим значением.

1 голос
/ 27 декабря 2013

Вы можете сделать что-то вроде этого:

import java.util.ArrayList;
import java.util.Iterator;

public class Miterate {

    abstract class IteratorCaster<E> implements Iterable<E>, Iterator<E> {
        int mIteratorIndex = 0;

        public boolean hasNext() {
            return mStorage.size() > mIteratorIndex;
        }

        public void remove() {
        }

        public Iterator<E> iterator() {
            return this;
        }
    }

    class FloatCast extends IteratorCaster<Float> {
        public Float next() {
            Float tFloat = Float.parseFloat((String)mStorage.get(mIteratorIndex));
            mIteratorIndex ++;
            return tFloat;
        }
    }

    class StringCast extends IteratorCaster<String> {
        public String next() {
            String tString = (String)mStorage.get(mIteratorIndex);
            mIteratorIndex ++;
            return tString;
        }
    }

    class IntegerCast extends IteratorCaster<Integer> {
        public Integer next() {
            Integer tInteger = Integer.parseInt((String)mStorage.get(mIteratorIndex));
            mIteratorIndex ++;
            return tInteger;
        }
    }

    ArrayList<Object> mStorage;

    StringCast mSC;
    IntegerCast mIC;
    FloatCast mFC;

    Miterate() {
        mStorage = new ArrayList<Object>();

        mSC = new StringCast();
        mIC = new IntegerCast();
        mFC = new FloatCast();


        mStorage.add(new String("1"));
        mStorage.add(new String("2"));
        mStorage.add(new String("3"));
    }

    Iterable<String> getStringIterator() {
        return mSC;
    }

    Iterable<Integer> getIntegerIterator() {
        return mIC;
    }

    Iterable<Float> getFloatIterator() {
        return mFC;
    }

    public static void main(String[] args) {
        Miterate tMiterate = new Miterate();

        for (String tString : tMiterate.getStringIterator()) {
            System.out.println(tString);
        }

        for (Integer tInteger : tMiterate.getIntegerIterator()) {
            System.out.println(tInteger);
        }

        for (Float tFloat : tMiterate.getFloatIterator()) {
            System.out.println(tFloat);
        }
    }
}
1 голос
/ 15 марта 2011

Да и нет.Это зависит от реализации интерфейса Iterable<T>.

Обычно он должен возвращать новый экземпляр класса, который реализует интерфейс Iterable, класс AbstractList реализует это следующим образом:

public Iterator<E> iterator() {
    return new Itr(); //Where Itr is an internal private class that implement Itrable<T>
}

ЕслиВы используете стандартные классы Java. Вы можете ожидать, что это будет сделано таким образом.

В противном случае вы можете выполнить простой тест, вызвав iterator() из объекта, а затем перебрать сначала и после этого второго, если они зависят, второе не должно давать никакого результата.Но это очень маловероятно.

0 голосов
/ 15 марта 2011

С одновременными коллекциями вы можете иметь несколько итераторов в разных потоках, даже если они вставляются и удаляются.

...