Javaコレクションフレームワークは、多数のデータをまとめて管理および処理するために用意されたもので、様々なタイプのインタフェースとクラスで構成されています。
これらのインタフェースはjava.util.Collectionとjava.util.Mapの2つのグループに分けることができます。
MapはCollectionを継承していないため狭義の意味ではコレクションではありませんが、Mapが持つ3つのコレクションビューにより、コレクション(データの集合)として扱うことができます。
コレクションフレームワークは、データ構造とアルゴリズムが提供されているため、開発コストの削減や、パフォーマンスの向上、設計コストの削減などのメリットがあります。
Collectionインタフェースは、複数の要素を保持するためのインタフェースです。Collectionは、List, Set, Queueなどのサブインタフェースを持ち、それらはそれぞれ異なる特徴を持っています。
Collectionインタフェースは、以下のようなメソッドを持っています。
これらのメソッドは実装がなく、サブクラスで実装されています。
また、Collectionインタフェースは、java.utilパッケージのjava.util.Iterableインタフェースを継承しています。Iterableインタフェースは、Javaで拡張for(for-each)文を使用できるようにするためのインタフェースです。Collectionインタフェースのサブクラスはすべて、for-each文でループすることができます。
インターフェースについては、プログラミングパラダイム/OOP/インターフェースで詳しく学習できます。
Listインタフェースは順序付きリストのコレクションで、インデックスによってリスト内の要素にアクセスすることができます。以下のクラスで実装されています。
VectorとStackについては古くからあるレガシーなクラスのため推奨されていません。Vectorはスレッドセーフが必要な場合はCollections.synchronizedListを使用し、それ以外はArrrayListを使うほうがパフォーマンスが良くなります。StackについてはDequeを使用するよう推奨されています。
ListとArrayListは以下のように使います。
// パッケージをimportします
import java.util.List;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
// AbstractCollectsionで実装されているtoString()メソッドが呼ばれるので[]の中に要素が表示される
System.out.println(list);
// インデックスを保持するためget(インデックス番号)で要素を取得
System.out.println(list.get(1));
// iterableインタフェースを継承しているので拡張for文が使えます
for(Integer i: list) {
System.out.println(i);
}
}
}
Setインタフェースは、Javaプログラミング言語におけるデータ構造の1つで、複数の要素を保持するコレクションを表します。Setは、要素の順序を保持せず、重複を許さないという特徴があります。Collectionを継承しているため、Collectionインタフェースに定義されているすべてのメソッドを使用することができます。
Setインタフェースを実装するクラスとしては、HashSetやTreeSetがあります。HashSetは、ハッシュテーブルを使用して要素を保存し、TreeSetは、集合内の要素を自然順序で保持します。内部の実装は、実際はMapインタフェースの実装クラスであるHashMapやTreeMapの実装へ処理を委譲しています。
Queueインタフェースは、Javaプログラミング言語におけるデータ構造の1つで、先入れ先出し(FIFO)のデータ構造を実装するためのインタフェースです。Collectionインタフェースを継承しているため、Collectionインタフェースに定義されているすべてのメソッドを使用することができます。
Queueインタフェースは、以下のようなメソッドを持っています。
Queueインタフェースを実装するクラスとしては、LinkedListやArrayDequeがあります。
import java.util.ArrayDeque;
import java.util.Queue;
class Main {
public static void main(String[] args) {
// ArrayDequeを使用したQueueの生成
Queue<String> queue = new ArrayDeque<>();
// 要素のエンキュー
queue.offer("Alice");
queue.offer("Bob");
queue.offer("Charlie");
queue.offer("Dave");
// キューのサイズを取得
int size = queue.size();
System.out.println("Queue size: " + size); // "Queue size: 4"
// 先頭の要素を参照
String head = queue.peek();
System.out.println("Head of queue: " + head); // "Head of queue: Alice"
// 要素のデキュー
while (queue.peek() != null) {
String s = queue.poll();
System.out.println("Dequeued: " + s);
}
// "Dequeued: Alice"
// "Dequeued: Bob"
// "Dequeued: Charlie"
// "Dequeued: Dave"
}
}
Deque(Double-ended queue)は、Javaプログラミング言語におけるデータ構造の1つで、双方向キューを表すインタフェースです。Dequeは、両端から要素を追加したり削除したりできるデータ構造です。Dequeは、単方向のQueueインタフェースと比べて、より柔軟な操作ができるインタフェースです。
Dequeインタフェースは、java.utilパッケージのjava.util.Queueインタフェースを継承しています。そのため、Queueインタフェースに定義されているすべてのメソッドを使用することができます。
Dequeインタフェースは、以下のようなメソッドを持っています。
Dequeインタフェースを実装するクラスとしては、ArrayDequeやLinkedListがあります。
import java.util.ArrayDeque;
import java.util.Deque;
class Main {
public static void main(String[] args) {
// ArrayDequeを使用したDequeの生成
Deque<String> deque = new ArrayDeque<>();
// 要素の追加
deque.addFirst("Alice");
deque.addLast("Bob");
deque.addLast("Charlie");
deque.addLast("Dave");
// Dequeのサイズを取得
int size = deque.size();
System.out.println("Deque size: " + size); // "Deque size: 4"
// 先頭の要素を参照
String head = deque.peekFirst();
System.out.println("Head of deque: " + head); // "Head of deque: Alice"
// 末尾の要素を参照
String tail = deque.peekLast();
System.out.println("Tail of deque: " + tail); // "Tail of deque: Dave"
// 要素の削除
while (deque.peekFirst() != null) {
String s = deque.pollFirst();
System.out.println("Dequeued from head: " + s);
}
// "Dequeued from head: Alice"
// "Dequeued from head: Bob"
// "Dequeued from head: Charlie"
// "Dequeued from head: Dave"
}
}
Mapインタフェースは、Javaプログラミング言語におけるデータ構造の1つで、キーと値の組を保持するためのインタフェースです。Mapは、任意のオブジェクトをキーとして、任意の値を保持することができます。同じキーを使用して複数の値を保持することはできません。
Mapインタフェースは、以下のようなメソッドを持っています。
MapはCollectionインタフェースを実装していないので、Collectionで定義されたメソッドを使うことはできません。Mapインタフェースは、キーと値の組を保持するデータ構造ですが、そのキーや値を単独で参照することもできるように、コレクションビューを提供しています。
Mapインタフェースを実装するクラスとしては、HashMapやTreeMapがあります。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
class Main {
public static void main(String[] args) {
// HashMapの生成
Map<String, Integer> map = new HashMap<>();
// 要素の追加
map.put("Alice", 100);
map.put("Bob", 90);
map.put("Charlie", 80);
map.put("Dave", 70);
// キーを保持するSetを取得
Set<String> keySet = map.keySet();
// Setを繰り返し処理
for (String key : keySet) {
int value = map.get(key);
System.out.println(key + ": " + value);
}
// "Alice: 100"
// "Bob: 90"
// "Charlie: 80"
// "Dave: 70"
}
}