今日のコーディング中にcontainsAll()
(インターフェースメソッド)を発見しましたが、かなり滑らかに見えます。List
パフォーマンス/反復の観点から、これにどれだけの費用がかかるか知っている人はいますか?
ドキュメントはそれに関してあまり提供しませんでした。
.equals(..)
(注:質問で指定したように、これはリストに関するものです。他のコレクションの動作は異なります)つまり、O(n*m) です。ここで、n と m は両方のコレクションのサイズです。
public boolean containsAll(Collection<?> c) {
Iterator<?> e = c.iterator();
while (e.hasNext())
if (!contains(e.next()))
return false;
return true;
}
ソースを使用してください、ルーク:)
編集:Bozhoが指摘したように、あなたはList.containsAll()
どのオーバーライドについて尋ねていますCollection.containsAll()
。次のとりとめのないことは、主に後者に関係しています。
ほとんどのCollection
クラスはfromの実装をcontainsAll
AbstractCollection
使用します。これは次のようになります。
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
ただし、一部の実装が完全に異なる動作をするという保証はありません。実行時の動作が良くなったり悪くなったりする可能性があります。
上記の の実装はcontainsAll
、少なくとも O(n) になります。ここで、n は、渡すCollection
パラメーター内のアイテムの数と、それにかかる時間を加えたものです。contains
HashSet
/の場合、HashMap
これは O(1) (最良の場合、衝突なし) になる可能性があるため、全体の実行時間containsAll
は依然として O(n) になります。ArrayList
はcontains
O(m) かかります。ここで、m はリスト内の項目数 (パラメーターではありません) であるため、全体の時間はcontainsAll
O(n*m) になります。A.containsAll(B) を呼び出している場合
openjdk は、A.contains(b) を呼び出して B のすべての要素を繰り返します。
A.contains(b) は、a.equals(b) を呼び出して A のすべての要素を反復します。
これは、 open jdk 7のソースから取得したものです。
検討
n.ContainsAll(m)
考えられる最善のシナリオは O(m) であり、それは n が完全なハッシュ セットである場合です。
ソートされていないリストを考慮すると、O(n*log(n) + m*log(m)) アルゴリズムを考え出すことができます