Java Collections Framework実装のBig-Oサマリー?[閉まっている]


164

まもなく「Javaクラッシュコース」を教えるかもしれません。オーディエンスメンバーがBig-O表記を知っていると想定するのはおそらく安全ですが、さまざまなコレクション実装でのさまざまな操作の順序が何であるかを知っていると想定するのはおそらく安全ではありません。

私は時間をかけて自分で要約行列を生成することもできますが、それがパブリックドメインのどこかにすでに存在している場合は、それを再利用したいと思います(もちろん、適切なクレジットを使用します)。

誰かが何かポインタがありますか?


これは、いくつかの非常に一般的なJavaオブジェクトと、Big-O表記を使用してそれらの操作にかかるコストを説明するときに役立つことがわかったリンクです。objectissues.blogspot.com/2006/11/...
ニック・

パブリックドメインではありませんが、Maurice NaftalinとPhilip Wadlerによる優れたJava Generics and Collectionsは、さまざまなコレクションクラスに関する章でランタイム情報の概要を示しています。
Fabian Steeg、

回答:


149

このWebサイトはかなり良いですが、Javaに固有ではありません:http : //bigocheatsheet.com/ このリンクが機能しない場合の画像は次のとおりです


27
そして、これが答えとしてURLを使用しない理由です。そのドキュメント/サーバーは、私の知る限り、もう利用できません!
Jason Mock 2013

1
@ベンJリンクが機能しなくなった
Vikas V

Webアーカイブのリンクも壊れています。
MikeFHay 2013

新しい作業URLが追加されたようです。努力をありがとう、それは非常に役に立ちます。
Tejas C

1
@AndreaZilio LinkedList.remove(Object)は、あなたがすでに隣人を知っていると仮定して、一定の時間です。隣人がわからない場合は、最初に見つけるのに線形時間です。
Paul Evans

217

書籍「Java Generics and Collections」にはこの情報があります(ページ:188、211、222、240)。

実装のリスト:

                      get  add  contains next remove(0) iterator.remove
ArrayList             O(1) O(1) O(n)     O(1) O(n)      O(n)
LinkedList            O(n) O(1) O(n)     O(1) O(1)      O(1)
CopyOnWrite-ArrayList O(1) O(n) O(n)     O(1) O(n)      O(n)

セット実装:

                      add      contains next     notes
HashSet               O(1)     O(1)     O(h/n)   h is the table capacity
LinkedHashSet         O(1)     O(1)     O(1) 
CopyOnWriteArraySet   O(n)     O(n)     O(1) 
EnumSet               O(1)     O(1)     O(1) 
TreeSet               O(log n) O(log n) O(log n)
ConcurrentSkipListSet O(log n) O(log n) O(1)

マップの実装:

                      get      containsKey next     Notes
HashMap               O(1)     O(1)        O(h/n)   h is the table capacity
LinkedHashMap         O(1)     O(1)        O(1) 
IdentityHashMap       O(1)     O(1)        O(h/n)   h is the table capacity 
EnumMap               O(1)     O(1)        O(1) 
TreeMap               O(log n) O(log n)    O(log n) 
ConcurrentHashMap     O(1)     O(1)        O(h/n)   h is the table capacity 
ConcurrentSkipListMap O(log n) O(log n)    O(1)

キューの実装:

                      offer    peek poll     size
PriorityQueue         O(log n) O(1) O(log n) O(1)
ConcurrentLinkedQueue O(1)     O(1) O(1)     O(n)
ArrayBlockingQueue    O(1)     O(1) O(1)     O(1)
LinkedBlockingQueue   O(1)     O(1) O(1)     O(1)
PriorityBlockingQueue O(log n) O(1) O(log n) O(1)
DelayQueue            O(log n) O(1) O(log n) O(1)
LinkedList            O(1)     O(1) O(1)     O(1)
ArrayDeque            O(1)     O(1) O(1)     O(1)
LinkedBlockingDeque   O(1)     O(1) O(1)     O(1)

java.utilパッケージのjavadocの下部には、いくつかの優れたリンクが含まれています。


3
どちらのケースのシナリオがこれらの数値であるかを指定する必要があります。たとえば、配列の中央または最後の要素を削除すると、Arraylistからの削除でO(n)が発生する可能性があります。
ポパイ2017

@popeyeは、通常、最悪のケースではありませんか?
Yassin Hajaj

@Popeyeが述べたように、答えがどのようなケースであるかについての明確な説明があるはずです。ケースは、時間の複雑さのために、平均/最悪のいずれかになります。答えはすべてのDSの「平均的な」ケースを参照しているようです。
Yashwin Munsadwala

12

各コレクションクラスのSunのJavadocは、通常、必要なものを正確に伝えます。HashMap、例えば:

この実装は、ハッシュ関数がバケット間で要素を適切に分散すると仮定して、基本操作(getおよびput)に一定時間のパフォーマンスを提供します。コレクションビューの反復には、HashMapインスタンスの "容量"(バケットの数)とそのサイズ(キーと値のマッピングの数)の合計に比例した時間が必要です。

TreeMap

この実装は、containsKey、get、put、およびremoveオペレーションの保証されたlog(n)時間コストを提供します

TreeSet

この実装は、基本的な操作(追加、削除、および包含)に対して保証されたlog(n)時間コストを提供します

(強調鉱山)


HashMapの部分に同意しません。私はSunの位置を知っていますが、たとえばgetはobj.equals(key)を呼び出す必要があります。通常、この比較のためにフィールドを読み取る必要があることを考慮してください。例外は整数または文字列(インターン)ですか???
オーバーフロー

まず最初に、それらが間違っていたとしても、一定時間のパフォーマンスを反証するテストケースを作成することはそれほど難しくないはずです。次に、HashMapのソースコードを見ると、マップ内の各キーに対してequals()は呼び出されません。ハッシュコードが等しい場合のみです。
マットb

5
上記の引用を読むと、「ハッシュ関数が要素をバケット間で適切に分散していると仮定して」一定時間であることがわかります。CS理論から、ハッシュテーブルは、ハッシュ関数が「良好」(平均的に発生)である場合は一定の時間操作を行いますが、最悪の場合は線形時間がかかる場合があります。
newacct 2009年

4
@Overflown-技術的には、obj.equals()が複雑さの観点からどれだけ長くかかるかは問題ではありません。これは、コレクション内のアイテム数に関する「定数」の一部にすぎないためです。
mikera

6

上記の人は、HashMap / HashSetとTreeMap / TreeSetを比較しました。

ArrayListとLinkedListについて話します。

配列リスト:

  • O(1) get()
  • 償却済みO(1) add()
  • あなたが挿入または削除要素を途中で使用している場合ListIterator.add()Iterator.remove()、以下のすべての要素をシフトするためにO(n)となります

LinkedList:

  • オン) get()
  • O(1) add()
  • あなたが挿入または削除要素を途中で使用している場合ListIterator.add()Iterator.remove()、それはO(1)になります

1
if you insert or delete an element in the middle using ListIterator.add() or Iterator.remove(), it will be O(1) どうして?最初に中央の要素を見つける必要があるので、なぜO(n)でないのですか?
MyTitle 2013年

@MyTitle:もう一度読んでください。「ListIterator.add()またはIterator.remove()」を使用して、イテレータを作成しています。
newacct 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.