一部のコレクションデータ構造が挿入の順序を維持しないのはなぜですか?挿入の順序を維持することと比較して達成される特別なことは何ですか?順序を維持しないと何かを得られますか?
パフォーマンス。元の挿入順序が必要な場合は、LinkedXXXクラスがあり、追加のリンクリストを挿入順序で維持します。ほとんどの場合、気にしないので、HashXXXを使用するか、自然な順序が必要なため、TreeXXXを使用します。どちらの場合でも、リンクリストの追加費用を支払う必要があるのはなぜですか?
コレクションは挿入の順序を維持しません。いくつかはデフォルトで最後に新しい値を追加するだけです。挿入の順序を維持することは、それによってオブジェクトに優先順位を付けるか、それを使用して何らかの方法でオブジェクトをソートする場合にのみ役立ちます。
一部のコレクションがデフォルトでそれを維持し、他のコレクションがそれを維持しない理由については、これは主に実装によって引き起こされ、コレクション定義の一部のみであることがあります。
Lists末尾または先頭に新しいエントリを追加するだけでadd(Object)メソッドの最速の実装であるため、挿入順序を維持します。
Sets HashSetおよびTreeSetの実装は、オブジェクトが高速ルックアップのためにソートされ、挿入順序を維持するには追加のメモリが必要になるため、挿入順序を維持しません。セットの挿入順序はほとんど面白くないため、これによりパフォーマンスが向上します。
ArrayDeque dequeは単純なqueおよびstackに使用できるため、「先入れ先出し」または「先入れ先出し」の動作が必要です。どちらもArrayDequeが挿入順序を維持する必要があります。この場合、挿入順序はクラス契約の中心部分として維持されます。
LinkedHashMap
のように)挿入順序を維持するためのロジックを追加することは可能ですが、それはより多くのコードを必要とし、実行時により多くのメモリと時間を必要とします。通常、パフォーマンスの低下は重大ではありませんが、重大な場合があります。TreeSet/Map
、それらを使用する主な理由は、自然な反復順序とSortedSet/Map
インターフェイス。実装がうまくいくために必要なものに依存します。通常、挿入順序は重要ではないため、挿入順序を維持する必要がないため、再配置してパフォーマンスを向上させることができます。
マップの場合、通常使用されるのはHashMapとTreeMapです。ハッシュコードを使用すると、エントリを検索しやすい小さなグループに入れることができます。TreeMapは、検索速度は遅くなりますが、HashMapよりも簡単にソートできますが、挿入されたエントリのソート順を維持します。
HashSet(またはHashMap)を使用すると、データはオブジェクトのハッシュに基づいて「バケット」に保存されます。この方法では、セット全体でこの特定のデータを探す必要がなく、正しいバケットを調べるだけでよいため、データにアクセスしやすくなります。
これにより、特定のポイントでパフォーマンスを向上させることができます。
各Collection実装には、特定の条件での使用を改善するための特殊性があります。これらの特殊性にはそれぞれコストがかかります。そのため、実際にそれを必要としない場合(例えば、挿入順序)、それを提供せず、要件によりよく適合する実装を使用する方が適切です。
挿入の順序を維持する必要があるのはなぜですか? HashMap
を使用する場合、key
でエントリを取得できます。それはあなたが望むことをするクラスを提供しないという意味ではありません。
O'Reilly Java Cookbookには「並べ替えの衝動を避ける」というセクションがあります。あなたが尋ねるべき質問は、実際には元の質問の反対です...「並べ替えによって何かを得ますか?」その順序をソートして維持するには、多くの労力が必要です。確かにソートは簡単ですが、ほとんどのプログラムでは通常、スケーリングしません。 1秒間に数千または数万のリクエスト(insrt、del、getなど)を処理する場合、ソートされたデータ構造またはソートされていないデータ構造を使用しているかどうかは重大な問題になります。
一部のコレクションは、コンテンツのhashCodeを計算して適切なバケットに適切に保存するため、順序を維持しません。