Какая-либо большая разница между использованием содержит или цикл через список?

Мудрая производительность, там действительно большая разница между использованием:

  • ArrayList.contains (o) по сравнению с foreach|iterator
  • LinkedList.contains (o) по сравнению с foreach|iterator

Конечно, для foreach|iterator циклов, я должен буду явно сравнить методы и возвратить TRUE или FALSE соответственно.

Объект, который я сравниваю, является объектом где equals() и hashcode() оба правильно переопределяются.

Править: Не должны знать о containsValue, в конце концов, извините об этом. И да, я глуп... Я понял, насколько глупый мой вопрос был о containsKey по сравнению с foreach, nevermind об этом, я не знаю то, что я думал. Я в основном хочу знать о тех выше (вырезал другие).

9
задан Ricardo Amaral 21 May 2010 в 22:08
поделиться

6 ответов

РЕДАКТИРОВАТЬ:

С новой формой вопроса, больше не включающей HashMap и TreeMap, мой ответ совершенно другой. Теперь я говорю нет .

Я уверен, что другие люди ответили на этот вопрос, но как в LinkedList, так и в ArrayList, contains () просто вызывает indexOf (), который выполняет итерацию по коллекции.

Возможно, есть крошечные различия в производительности как между LinkedList и ArrayList, так и между contains и foreach, нет никаких больших различий.

9
ответ дан 4 December 2019 в 10:30
поделиться

Без тестирования, содержит во всех случаях должен быть быстрее или одинаково.

Для 1 и 2 нет необходимости вызывать методы итератора. Он может зацикливаться внутри. Реализация как ArrayList, так и LinkedList содержит в терминах indexOf

  1. ArrayList - indexOf - это цикл for в стиле C в массиве поддержки.
  2. LinkedList - indexOf просматривает связанный список в цикле for в стиле C.

Для 3 и 4 необходимо различать containsKey и containsValue.

3. HashMap , containsKey равен O (1). Он работает путем хеширования ключа, получения связанной корзины и последующего просмотра связанного списка. containsValue имеет значение O (n) и работает, просто проверяя каждое значение в каждом сегменте во вложенном цикле for.

4. TreeMap , containsKey равен O (log n). Он проверяет, находится ли он в пределах досягаемости, а затем ищет в красно-черном дереве. containsValue, который равен O (n), использует обход дерева по порядку.

3
ответ дан 4 December 2019 в 10:30
поделиться

Это не делает различий, поскольку contains (o) вызывает indexOf (o), который просто зацикливается следующим образом:

for (int i = 0; i < size; i++)
    if (o.equals(elementData[i]))
       return i;

(Проверено в ArrayList)

6
ответ дан 4 December 2019 в 10:30
поделиться

ArrayList.contains does

return indexOf(o) >= 0;

где

public int indexOf(Object o) {
if (o == null) {
    for (int i = 0; i < size; i++)
    if (elementData[i]==null)
        return i;
} else {
    for (int i = 0; i < size; i++)
    if (o.equals(elementData[i]))
        return i;
}
return -1;
}

Он похож на LinkedList, только он использует .next () для итерации по элементам, поэтому особой разницы нет.

public int indexOf(Object o) {
    int index = 0;
    if (o==null) {
        for (Entry e = header.next; e != header; e = e.next) {
            if (e.element==null)
                return index;
            index++;
        }
    } else {
        for (Entry e = header.next; e != header; e = e.next) {
            if (o.equals(e.element))
                return index;
            index++;
        }
    }
    return -1;
}

HashMap.containKey использует хэш ключа для получения всех ключей с этим хешем (что происходит быстро), а затем использует равенства только для этих ключей, так что в этом есть улучшение; но containsValue () перебирает значения с for.

TreeMap.containsKey, похоже, выполняет информированный поиск с использованием компаратора, чтобы найти ключ быстрее, а это еще лучше; но кажется, что containsValue проходит через все три, пока не найдет значение.

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

2
ответ дан 4 December 2019 в 10:30
поделиться

Я думаю, что использование contains лучше, потому что в целом реализация библиотеки более эффективна, чем ее реализация вручную. Проверьте, можете ли вы во время создания объекта или после него передать написанный вами метод компаратора, который позаботится о ваших пользовательских равнях и реализации хэш-кода.

Спасибо, Кришна

0
ответ дан 4 December 2019 в 10:30
поделиться

Обход контейнера с помощью foreach/iterator всегда занимает O(n) времени. Поиск в ArrayList/LinkedList также O(n).

HashMap.containsKey() - O(1) амортизированное время.

TreeMap.containsKey() - O(log n) времени.

Для HashMap и TreeMap containsValue() - O(n), но могут быть реализации, оптимизированные для того, чтобы containsValue() был таким же быстрым, как containsKey().

0
ответ дан 4 December 2019 в 10:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: