Collections Frameworkの概要
入門
Javaプラットフォームには、Collections Frameworkが追加されました。 collectionは、オブジェクトのグループ(古典的なArrayListクラス)を表すオブジェクトです。 Collections Frameworkとは、コレクションを表したり操作したりする、統一されたアーキテクチャのことで、実装の詳細に依存しない方法でコレクションを操作することができます。Collections Frameworkの主な利点は、次のとおりです。
- プログラミングの労力の軽減 - データ構造とアルゴリズムが提供されているため、新しく記述する必要がない。
- パフォーマンスの向上 - データ構造とアルゴリズムの高性能な実装が提供されている。 各インタフェースのさまざまな実装は、相互に交換できるため、実装を交換するだけでプログラムをチューン・アップできる。
- 関連性のないAPI間の相互運用が可能 - コレクションの受け渡しを可能にする共通言語が確立されている。
- APIの学習に必要な労力を軽減 - 特定の場面でだけ必要なコレクションAPIをいくつも学ぶ必要がある。
- APIの設計と実装に必要な労力を軽減 - 特定の場面でだけ必要なコレクションAPIを作成する手間を省く。
- ソフトウェアの再利用を促進 - コレクションやアルゴリズムを操作するためのインタフェースを提供する。
Collections Frameworkは、次の要素で構成されます。
- コレクション・インタフェース。 セット、リスト、およびマップなど、種類ごとに異なるコレクションを表す。 これらのインタフェースが、フレームワークの基礎を構成する。
- 汎用の実装。 コレクション・インタフェースのプライマリ実装。
- レガシー実装。
Vector
やHashtable
など、以前にリリースされたコレクション・クラスが改良されて、コレクション・インタフェースを実装した。 - 特殊目的の実装。 特殊な状況で使用するための実装。 これらの実装は、非標準の性能、使用制約、動作を表示。
- 並列実装。 高度な並列使用で使用するための実装。
- ラッパー実装。 ほかの実装に、同期化などの機能を追加する。
- 簡易実装。 コレクション・インタフェースの高性能な「ミニ実装」。
- 抽象実装。 カスタム実装を容易にする、コレクション・インタフェースの部分実装。
- アルゴリズム リストのソートなど、コレクションに対し、有用な機能を実行する静的メソッド。
- インフラストラクチャ コレクション・インタフェースの根幹をサポートするインタフェース。
- 配列ユーティリティ。 プリミティブ配列および参照オブジェクト配列用のユーティリティ機能。 厳密に言えば、この機能はCollections Frameworkの一部ではないが、Collections Frameworkと同時期にJavaプラットフォームに追加され、同じインフラストラクチャに依存している。
コレクション・インタフェース
コレクション・インタフェースは2つのグループにわかれます。 もっとも基本的なインタフェースはjava.util.Collection
で、次の子孫があります。
java.util.Set
java.util.SortedSet
java.util.NavigableSet
java.util.List
java.util.Queue
java.util.concurrent.BlockingQueue
java.util.concurrent.TransferQueue
java.util.Deque
java.util.concurrent.BlockingDeque
そのほかのコレクション・インタフェースは、java.util.Map
に基づいていて、真の意味でのコレクションではありません。 ただし、これらのインタフェースにはcollection-viewオペレーションが含まれているため、コレクションとして操作することが可能です。 Map
には、次の子孫があります。
java.util.SortedMap
java.util.NavigableMap
java.util.concurrent.ConcurrentMap
java.util.concurrent.ConcurrentNavigableMap
コレクション・インタフェースの変更メソッドの多くには、オプションというラベルが付いています。 実装では、これらのオペレーションのいくつかが試みられた場合に、それらを実行せず、実行時例外(UnsupportedOperationException
)をスローすることが許可されています。 各実装のドキュメントでは、サポートされるオプションのオペレーションを指定する必要があります。 この仕様を理解するための助けとして、いくつかの用語が導入されています。
- 変更操作(
add
、remove
、clear
など)をサポートしないコレクションのことを変更不可能であるという。 変更不可能ではないコレクションは変更可能である。 Collection
オブジェクト内にどのような変更も見られないことを保証するコレクションは、不変であるという。 不変ではないコレクションは可変である。- 要素は変化しても、サイズが定数値であることが保証されたリストは、固定サイズであるという。 固定サイズでないリストは、可変サイズであるという。
- 高速(通常は一定時間)インデックスの付いた要素のアクセスをサポートするリストは、ランダム・アクセス・リストと呼ばれる。 高速インデックスの付いた要素のアクセスをサポートしないリストは、順次アクセス・リストと呼ばれる。
RandomAccess
マーカー・インタフェースを使用すると、リストでランダム・アクセスをサポートすることを通知することができる。 これによりジェネリック・アルゴリズムがランダム・アクセス・リストまたは順次アクセス・リストのいずれかに適用されるとき、その動作を変更してパフォーマンスを向上することができる。
実装によっては、格納する要素(Maps
の場合はキーおよび値)を限定する場合があります。 要素を限定する条件には、次のようなものがあります。
- 特定の型。
- null以外。
- 任意に選んだある述語に適合。
実装の制限に適合しない要素を追加しようとすると、実行時例外が発生します。典型的な実行時例外には、ClassCastException
、IllegalArgumentException
、またNullPointerException
があります。 実装の制限に適合しない要素を削除またはテストしようとすると、例外が発生することがあります。 制限付きのコレクションによっては、その使用法を許可していることがあります。
コレクションの実装
一般に、コレクション・インタフェースを実装するクラスは、<Implementation-style><Interface>という形式の名前を持ちます。 次の表に、汎用の実装の概要を示します。
インタフェース | ハッシュ表 | サイズ変更可能な配列 | バランス・ツリー | リンク・リスト | ハッシュ表+リンク・リスト |
---|---|---|---|---|---|
Set |
HashSet |
TreeSet |
LinkedHashSet |
||
List |
ArrayList |
LinkedList |
|||
Queue, Deque |
ArrayDeque |
LinkedList |
|||
Map |
HashMap |
TreeMap |
LinkedHashMap |
汎用の実装は、コレクション・インタフェースのオプションのオペレーションをすべてサポートしています。また、格納する要素に制限はありません。 これらの実装は非同期ですが、Collections
クラスには、同期ラッパーと呼ばれるstaticファクトリが含まれます。同期ラッパーは、同期をとらない多くのコレクションに同期をとる機能を追加するために使用されます。 新規の実装にはすべて、フェイルファスト・イテレータが含まれます。フェイルファスト・イテレータは、無効な並列変更を探知し、すばやくクリーンにフェイルします。不規則な動作はしません。
AbstractCollection
、AbstractSet
、AbstractList
、AbstractSequentialList
、およびAbstractMap
クラスは、コア・コレクション・インタフェースの基本的な実装を提供し、実装に必要な手間を最小限に抑えます。 これらのクラスのAPIドキュメントには、各メソッドがどのように実装されているかが説明されているため、実装者は、特定の実装の「基本オペレーション」のパフォーマンスに基づき、どのメソッドをオーバーライドしたらよいかがわかります。
並行処理コレクション
複数のスレッドからのコレクションを使用するアプリケーションは、慎重にプログラミングする必要があります。 一般に、これは並行プログラミングと呼ばれます。 Javaプラットフォームは、並行プログラミングを幅広くサポートします。 詳細については、「Java並行処理ユーティリティ」を参照してください。
コレクションは使用頻度が高いため、コレクションの並行処理に適した各種のインタフェースおよび実装がAPIに含まれています。 これらのタイプは、前述の同期ラッパーを超えて、並行プログラミングで頻繁に必要とされる機能を提供します。
並行処理に対応するこれらのインタフェースを使用できます。
並列処理に対応する次の実装クラスを使用できます。 これらの実装の適切な使用法については、APIドキュメントを参照してください。
LinkedBlockingQueue
ArrayBlockingQueue
PriorityBlockingQueue
DelayQueue
SynchronousQueue
LinkedBlockingDeque
LinkedTransferQueue
CopyOnWriteArrayList
CopyOnWriteArraySet
ConcurrentSkipListSet
ConcurrentHashMap
ConcurrentSkipListMap
設計上の目標
設計上の主要な目標は、実際のサイズにおいて、またより重要性の高い「概念の重さ」においても小さいAPIを作成することでした。 現在のJavaプログラマにとって、この新機能が大きく違うものには見えないようにするということも非常に重要な点でした。このため、既存の機能を置き換えるのではなく、機能を追加する必要がありました。 同時に、この新しいAPIは、前述の利点すべてを提供できるような強力なものにする必要がありました。
コア・インタフェースを小さく保つために、インタフェースはこのようなわずかな違いを可変、修正、サイズ変更としてはとらえません。 コア・インタフェースでのある種の呼出しはオプションであり、実装は、特定の省略可能なオペレーションに関してはUnsupportedOperationException
をスローして、サポートしないことを示せるようにしました。 コレクションの実装者は、実装がオプションのオペレーションのうち、どれをサポートしているかをドキュメントに明示する必要があります。
各コア・インタフェース内のメソッドの数を少数に保つために、メソッドが次のどれかの場合にだけ、インタフェースはメソッドを格納します。
- 真に基礎的なオペレーションである。つまり、このメソッドを利用してほかのメソッドを定義可能である。
- 重要な実装がそのメソッドをオーバーライドすることを望むだけの、パフォーマンス上の強力な理由がある。
コレクションの妥当な表現が、すべて相互運用可能であることは重要な要件です。 この表現には配列が含まれます。配列は、言語を変えずに直接Collection
インタフェースを実装することはできません。 このため、フレームワークには、コレクションを配列に移動すること、配列をコレクションとみなすこと、およびマップをコレクションとみなすことを可能にするメソッドが含まれています。
Copyright © 1998, 2021, Oracle and/or its affiliates. 500 Oracle Parkway
Redwood Shores, CA 94065 USA. All rights reserved.