Почему it.current меняет свои значения во время отладки?

Я пытаюсь получить элемент по определенному индексу с помощью метода:

public T GetElem(int index)
{
    var it = outerInstance.iterator();
    var i = 0;
    while (it.MoveNext() && i < index)
    {
        i++;
    }
    return it.Current;
}

Я создал свой собственный итератор, который является внутренним классом externalInstance, во время отладки текущий элемент уменьшается, в конце он становится нулевым.

Мой тест находится внутри консольного приложения и выглядит так:

Storage<int?> storage = new DynSLinkedList<int?>();
var ranked = new Ranked<int?>(storage);

if (ranked.IsEmpty())
{
    Console.WriteLine("is empty \n");
}

for (var i = 1; i <= 10; i++)
    ranked.Add(i);

if (!ranked.IsEmpty())
{
    Console.WriteLine("is not empty \n");
}

if (ranked.Size() == 10)
{
    Console.WriteLine("Size ok \n");
}

for (var i = 0; i <= 9; i++)
{
    var element = ranked.GetElem(i);
    if (element == 10 - i)
    {
        Console.WriteLine("get " + i + " elem ok \n");
    }
}

Только для i=0 это правильно.

введите описание изображения здесь

введите описание изображения здесь

Я попытался написать эквивалент для метода Java:

@Override
public T getElem(int index) throws IndexOutOfBoundsException {
    RWIterator<T> it=support.iterator();
    int i=0;
    while (it.hasNext() && i<index){
        it.next();
        i++;
    }
    return it.next();
}

1 ответ

Решение

Ваша проблема в том, что вы используете один экземпляр для итерации в методе Ranked.GetElem. При первом вызове ranked.GetElem, передав 0, итератор будет перемещен на один шаг (it.MoveNext).

На этом этапе итератор уже указывает на второй элемент в вашем списке. В следующий раз, когда вы вызовете ranked.GetElem, пройдя 1, итератор будет перемещен на два интервала дальше, в результате чего будет возвращен третий элемент в отличие от того, который вы ожидаете (второй). Так далее и тому подобное.

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

Попробуйте это (при условии, что вы правильно реализуете метод Reset()):

public T GetElem(int index)
{
    var it = outerInstance.iterator();
    it.Reset();
    var i = 0;
    while (it.MoveNext() && i < index)
    {
        i++;
    }
    return it.Current;
}
Другие вопросы по тегам