Мудрая производительность, там действительно большая разница между использованием:
Конечно, для foreach|iterator циклов, я должен буду явно сравнить методы и возвратить TRUE или FALSE соответственно.
Объект, который я сравниваю, является объектом где equals()
и hashcode()
оба правильно переопределяются.
Править: Не должны знать о containsValue, в конце концов, извините об этом. И да, я глуп... Я понял, насколько глупый мой вопрос был о containsKey по сравнению с foreach, nevermind об этом, я не знаю то, что я думал. Я в основном хочу знать о тех выше (вырезал другие).
РЕДАКТИРОВАТЬ:
С новой формой вопроса, больше не включающей HashMap и TreeMap, мой ответ совершенно другой. Теперь я говорю нет .
Я уверен, что другие люди ответили на этот вопрос, но как в LinkedList, так и в ArrayList, contains () просто вызывает indexOf (), который выполняет итерацию по коллекции.
Возможно, есть крошечные различия в производительности как между LinkedList и ArrayList, так и между contains и foreach, нет никаких больших различий.
Без тестирования, содержит во всех случаях должен быть быстрее или одинаково.
Для 1 и 2 нет необходимости вызывать методы итератора. Он может зацикливаться внутри. Реализация как ArrayList, так и LinkedList содержит в терминах indexOf
Для 3 и 4 необходимо различать containsKey и containsValue.
3. HashMap , containsKey равен O (1). Он работает путем хеширования ключа, получения связанной корзины и последующего просмотра связанного списка. containsValue имеет значение O (n) и работает, просто проверяя каждое значение в каждом сегменте во вложенном цикле for.
4. TreeMap , containsKey равен O (log n). Он проверяет, находится ли он в пределах досягаемости, а затем ищет в красно-черном дереве. containsValue, который равен O (n), использует обход дерева по порядку.
Это не делает различий, поскольку contains (o) вызывает indexOf (o), который просто зацикливается следующим образом:
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
(Проверено в ArrayList)
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 проходит через все три, пока не найдет значение.
В целом, я считаю, что вам следует использовать эти методы, поскольку их проще написать, чем каждый раз выполнять цикл :).
Я думаю, что использование contains лучше, потому что в целом реализация библиотеки более эффективна, чем ее реализация вручную. Проверьте, можете ли вы во время создания объекта или после него передать написанный вами метод компаратора, который позаботится о ваших пользовательских равнях и реализации хэш-кода.
Спасибо, Кришна
Обход контейнера с помощью foreach/iterator всегда занимает O(n) времени. Поиск в ArrayList/LinkedList также O(n).
HashMap.containsKey() - O(1) амортизированное время.
TreeMap.containsKey() - O(log n) времени.
Для HashMap и TreeMap containsValue() - O(n), но могут быть реализации, оптимизированные для того, чтобы containsValue() был таким же быстрым, как containsKey().