Подтвердить что ты не робот

Каков наилучший способ получить счетчик/длину и размер итератора?

Есть ли "вычислительный" быстрый способ получить счетчик итератора?

int i = 0;
for ( ; some_iterator.hasNext() ; ++i ) some_iterator.next();

... кажется пустой тратой циклов процессора.

4b9b3361

Ответ 1

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

Однако многие итераторы поступают из коллекций, которые вы часто можете запрашивать по их размеру. И если это пользовательский класс, на который вы получаете итератор, вы можете посмотреть, как предоставить метод size() для этого класса.

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

Ответ 2

Использование библиотеки Guava:

int size = Iterators.size(iterator);

Внутри он просто выполняет итерации по всем элементам, поэтому просто для удобства.

Ответ 3

Ваш код даст вам исключение, когда вы достигнете конца итератора. Вы можете сделать:

int i = 0;
while(iterator.hasNext()) {
    i++;
    iterator.next();
}

Если у вас был доступ к основной коллекции, вы могли бы вызвать coll.size()...

ИЗМЕНИТЬ ОК вы внесли поправки...

Ответ 4

Нет лучшего способа, если все, что у вас есть, это итератор.

Решение состоит в том, чтобы изменить ваше приложение, чтобы оно не нуждалось в подсчете, или получить его каким-либо другим способом. (Например, передайте Collection, а не Iterator...)

Ответ 5

Если у вас есть итератор, то нет, нет "лучшего" способа. Если итератор поступает из коллекции, вы могли бы как это сделать для размера.

Имейте в виду, что Iterator - это просто интерфейс для прохождения различных значений, у вас будет очень хороший код, например

    new Iterator<Long>() {
        final Random r = new Random();
        @Override
        public boolean hasNext() {
            return true;
        }

        @Override
        public Long next() {
            return r.nextLong();
        }

        @Override
        public void remove() {
            throw new IllegalArgumentException("Not implemented");
        }
    };

или

    new Iterator<BigInteger>() {
        BigInteger next = BigInteger.ZERO;

        @Override
        public boolean hasNext() {
            return true;
        }

        @Override
        public BigInteger next() {
            BigInteger current = next;
            next = next.add(BigInteger.ONE);
            return current;
        }

        @Override
        public void remove() {
            throw new IllegalArgumentException("Not implemented");
        }
    }; 

Ответ 6

Другой вариант - преобразовать Iterable в List.

int count = Lists.newArrayList(some_iterator).size();

Ответ 7

Объект итератора содержит то же количество элементов, что и ваша коллекция.

List<E> a =...;
Iterator<E> i = a.iterator();
int size = a.size();//Because iterators size is equal to list a size.

Но вместо того, чтобы получать размер итератора и итерации с помощью индекса 0 до этого размера, лучше выполнить итерацию с помощью метода next() итератора.