web-dev-qa-db-ja.com

JavaのHashMap.containsKey()の時間の複雑さは何ですか?

私は知っておく必要があります:javaのHashMap.containsKey()の時間の複雑さは何ですか?

46
Hossein

_API doc of_ HashMap から:

この実装は、ハッシュ関数がバケット間で要素を適切に分散すると仮定して、基本操作(getおよびput)に一定時間のパフォーマンスを提供します。

containsKey()は取得した値を捨てるget()にすぎないため、O(1)(ハッシュ関数が適切に機能すると仮定))です。

55

通常O(1)ですが、不適切なhashCode関数を使用している場合は、1つのバケットに複数の要素を追加して、最悪の場合O(n)になるようにする必要があります。

13
mishadoff

一般的には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       }
9
Jigar Joshi

containsKeyの時間の複雑さはJDK-1.8で変更されました。他の人が述べたように、理想的なケースではO(1)です。ただし、keysComparableである衝突の場合、衝突要素を格納するビンは、TREEIFY_THRESHOLDと呼ばれるしきい値を超えた後、線形ではなくなります。

/**
 * 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のサイズです

6
Sleiman Jneidi