Какова временная сложность HashMap.containsKey() в java?

Мне нужно знать: какова временная сложность HashMap.containsKey() в java?


person Hossein    schedule 19.01.2012    source источник
comment
@OlegSklyar Этот вопрос помог мне, потому что мне пришлось самому реализовать HashMap.   -  person trinity420    schedule 12.05.2017
comment
@ trinity420 Таким образом, это оправдывает отказ от чтения документации API, когда у вас есть вопрос об API?   -  person Oleg Sklyar    schedule 12.05.2017
comment
Java 8: лучший случай O (1), худший случай O (log n)   -  person Hanash Yaslem    schedule 17.10.2020


Ответы (4)


Из API doc ofHashMap:

Эта реализация обеспечивает постоянную производительность для основных операций (получение и размещение), предполагая, что хэш-функция правильно распределяет элементы по корзинам.

Поскольку containsKey() — это просто get(), который отбрасывает полученное значение, это O (1) (при условии, что хеш-функция снова работает правильно).

person Michael Borgwardt    schedule 19.01.2012
comment
это то, что я думал раньше. Но это неправильно. Взгляните на ответ Джигара Джоши. Ваш ответ правильный для Hashtable, который не допускает нулевых значений. - person AlexR; 19.01.2012
comment
@AlexR: я думаю, вы совершенно неправильно понимаете код в ответе Джигара. Это не имеет абсолютно никакого отношения к нулевым значениям, и цикл for только перебирает связанный список записей в одном сегменте, что составляет O (1), если, как дважды указано в моем ответе, хеш-функция выполняет свою работу. - person Michael Borgwardt; 19.01.2012
comment
@Tom Hawtin - tackline: я не думаю, что это тот случай, о котором нужно беспокоиться большинству людей (нет, это не включает людей, которые пишут контейнеры сервлетов). - person Michael Borgwardt; 19.01.2012
comment
@TomHawtin-tackline, немного странно, что нет популярной хэш-карты. который использует дерево для столкновений. Так что это O (logN) в худшем случае и O (1) в противном случае. - person bestsss; 04.02.2012
comment
@bestsss Да. Это очевидная структура данных, но она требует, чтобы тип ключа поддерживал как хеш-интерфейсы, так и интерфейсы упорядочения, и делал это последовательно. Кроме того, постоянные факторы производительности также важны в реальной жизни. В ситуациях с хорошим поведением столкновения станут медленнее. Тем не менее, это реализация карты, которую я хотел бы видеть в java.util. - person Tom Hawtin - tackline; 05.02.2012
comment
@TomHawtin-tackline, подключаемый компаратор может учитывать порядок. Но столкновение не должно быть медленнее, скажем, дерево используется только после 4+ столкновений, и оно может быть другим типом (подклассом) Entry при построении на дереве. - person bestsss; 05.02.2012

Обычно O(1), но если мы используем плохую функцию hashCode, нам нужно добавить несколько элементов в одно ведро, чтобы в худшем случае это могло быть O(n).

person mishadoff    schedule 19.01.2012

Обычно это O(1), но в худшем случае это O(n)

 public boolean containsKey(Object key) {
  352           return getEntry(key) != null;
  353       }
  354   
  355       /**
  356        * Returns the entry associated with the specified key in the
  357        * HashMap.  Returns null if the HashMap contains no mapping
  358        * for the key.
  359        */
  360       final Entry<K,V> getEntry(Object key) {
  361           int hash = (key == null) ? 0 : hash(key.hashCode());
  362           for (Entry<K,V> e = table[indexFor(hash, table.length)];
  363                e != null;
  364                e = e.next) {
  365               Object k;
  366               if (e.hash == hash &&
  367                   ((k = e.key) == key || (key != null && key.equals(k))))
  368                   return e;
  369           }
  370           return null;
  371       }
person jmj    schedule 19.01.2012
comment
Тогда это будут Ω(1) и O(n). - person Viruzzo; 19.01.2012
comment
См. Ответ mishadoff для объяснения наихудшего случая. - person cellepo; 22.10.2015
comment
В худшем случае для Java 1.8 это O(log n). - person Hanash Yaslem; 17.10.2020

Временная сложность containsKey изменилась в JDK-1.8, как упоминалось ранее, в идеальных случаях она равна O(1). Однако в случае столкновений, где keys равны Comparable, ячейки, хранящие элементы столкновения, перестают быть линейными после того, как они превышают некоторый порог, называемый TREEIFY_THRESHOLD, который равен 8,

/**
 * The bin count threshold for using a tree rather than list for a
 * bin.  Bins are converted to trees when adding an element to a
 * bin with at least this many nodes. The value must be greater
 * than 2 and should be at least 8 to mesh with assumptions in
 * tree removal about conversion back to plain bins upon
 * shrinkage.
 */
static final int TREEIFY_THRESHOLD = 8;

Другими словами, TreeNodes будет использоваться (аналогично тем, что в TreeMap) для хранения бинов (то есть: красно-черная древовидная структура), и это оставляет нам сложность O(lgn) в случае коллизий.

То же самое относится к get(key), где оба метода вызывают getNode внутренне.

Примечание: n здесь указан размер bin, а не HashMap

person Sleiman Jneidi    schedule 31.12.2015