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

Нужно ли нам когда-либо использовать Итераторы на ArrayList?

Вчера, когда я отвечал на вопрос получение ошибки ConcurrentModificationException при использовании итератора и удаления, я добавил уведомление о том, что

Не рекомендуется использовать итераторы, когда у вас есть ArrayLists.

Вам не нужно глубоко понимать этот вопрос, чтобы ответить на этот вопрос.

Там, у меня есть два комментария, что я ошибаюсь.

Мои аргументы:

  • Код гораздо менее читабельен с помощью итераторов.

  • Существует возможность поднять ConcurrentModificationException, которое трудно отлаживать.

Не могли бы вы объяснить?

Вопрос: Нужно ли нам когда-либо использовать Итераторы в ArrayList?

UPD

Это касается явного использования Iterator.

4b9b3361

Ответ 1

Большой вариант использования итераторов с ArrayLists - это когда вы хотите удалить элементы во время итерации. У вас есть только три безопасных решения:

  • используйте итератор и его метод remove
  • скопируйте элементы, которые вы хотите сохранить в другом списке.
  • джунгли с индексами

Предполагая, что вы не add, итерации, использование итератора является средним, чтобы избежать ConcurrentModificationException.

Аргумент читаемости субъективен. Лично я не считаю чисто декларируемый итератор менее удобочитаемым. И это не имеет большого значения, поскольку итератор - это безопасный способ повторить и удалить одновременно.

Ответ 2

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

Допустим, у нас есть объект, содержащий массив, и у вас есть интерфейс в этом объекте для добавления элементов в этот массив. Но вы делаете что-то вроде этого:

class MyClass
{
    private ArrayList<Item> myList;

    public MyClass()
    {
        myList = new ArrayList();
    }

    public addItem( Item item )
    {
         item.doSomething(); // Lets say that this is very important before adding the item to the array.
         myList.add( item );
    }
}

Теперь, если у меня был этот метод в классе выше:

public ArrayList getList()
{
    return myList;
}

Кто-то может получить ссылку на myList с помощью этого метода и добавить элементы в массив, без вызова item.doSomething(); Вот почему вы не должны возвращать ссылку на массив, но вместо этого возвращаете свой итератор. Можно получить любой элемент из массива, но он не может манипулировать исходным массивом. Таким образом, объект MyClass все еще контролирует его собственное состояние.

Это настоящая причина, почему итераторы были изобретены.

Ответ 3

Да, нам нужно. ArrayList - это просто реализация интерфейса List, поэтому часто ваш код обрабатывает список и даже не знает, что это ArrayList. Кроме того, новый синтаксис for-loop использует итераторы внутри.

Ответ 4

Отметьте это сообщение: http://www.xyzws.com/javafaq/what-is-the-advantage-of-using-an-iterator-compared-to-the-getindex-method/19

Использование итератора позволит избежать ошибки использования get (index) в LinkedList (очень медленно). Это имеет смысл, когда реализация списка неизвестна, просто используйте итератор. Что касается ArrayList, использование итератора будет по-прежнему достигать максимально возможной производительности с помощью get (index).

Таким образом, рекомендуется использовать итератор для итерации с точки зрения производительности.

Ответ 5

Вероятно, вы говорите о явном использовании итератора (поскольку оператор: также использует итератор за кулисами).

Предположим, что вы хотите иметь два "указателя", проходящих через массив, но скорость зависит от фактических значений элементов. Как бы вы это сделали без явного использования итераторов (и без элемента, конечно).

Например (псевдокод):

element1 = first element;
element2 = first element;
while(element1.hasNext && element2.hasNext)
{
    if(element1 * 2 < element)
    {
        element2 = element2.next;
    }
    else
    {
        element1 = element1.next;
    }

    //do something with the pair of elements
}

Ответ 6

Этот код гораздо менее читается с помощью итераторов.

Это ваше мнение, и я не разделяю его.

Существует возможность поднять ConcurrentModificationException, которое трудно отлаживать.

Возможно, существует ли использование итераторов или нет. Это исключение сообщает вам что-то полезное о вашем коде, которое вы могли бы вообще пропустить, что еще сложнее отладить.

Лично я предпочитаю писать точно код как между ArrayList и LinkedList, а компилятор или API реализуют детали.

Мораль заключается в том, что вы не должны передавать свое собственное неподтвержденное мнение как установленный факт.