プログラムでは、多数のデータを扱うことが多々あります。Java には複数のデータを扱うコレクションクラス群が用意されており、用途によってコレクションクラスを使い分けます。
この記事では、Java のコレクションクラスの使い方を解説していきます。
コレクションクラスとは
前述の通り、コレクションクラスは多数のデータをひとまとめにして扱うための Java のクラスで、よく使うクラスに ArrayList、 HashMap などがあります。
同じように「配列」も複数のデータを扱いますが、大きさ(要素数)が固定です。それに対し、コレクションは大きさは決まっておらず、必要な数だけデータをコレクションに追加することが可能で、データベースから取得した値を格納する時など、要素数が特定できないデータを格納する時にコレクションを使用します。
Java のコレクションは「List」「Set」「Map」3つのインターフェイスに大別され、コレクションクラスは役割に応じて、いずれかのインターフェイスを実装します。
3つのインターフェースの概要と、それを実装したコレクションクラスの代表例を見てみましょう。
Java.util.List
Listインターフェイスを実装したクラスは、順序付きのコレクションです。
順序付きのリストは、前から(要素0から)順番に要素を連なった形で格納します。要素に格納する値は重複されることができます、また、リストの使用者は任意の位置の要素を挿入または削除ができます。
この順序付きリストの List インターフェースを実装したコレクションクラスには、ArrayList や LInkedLIst、Stackなどのクラスがあります。
ArrayList
ArrayList は、Listインターフェイスを実装したクラスであり、順序付きのリストである。ArrayList は順序付きのリストとして最もよく使われます。
ArrayList の初期化は次のように行います。
// 要素の型が String の ArrayList を初期化
List<String> arrayList = new ArrayList<>();
初期化時に要素を指定する場合は、次のように記述します。
List<String> arrayList = new ArrayList<String>(Arrays.asList("Java", "Ruby", "Python"));
ArrayList は順序付きリストであるため、配列要素へは0から始める先頭からのインデックスを指定して要素にアクセスします。また、要素の値を取得するときは get メソッドを使用します。
// 要素の型が String の ArrayList を初期化
List<String> arrayList = new ArrayList<>();
// 要素を3つ追加(1番目:Java, 2番目:Ruby、3番目:Python)
arrayList.add("Java");
arrayList.add("Ruby");
arrayList.add("Python");
// 2番目の要素(インデックスとしては 1)にアクセス
System.out.println(arrayList.get(1));
■ 実行結果
Ruby
LinkedList
LinkedList は ArrayList と同じ順序付きリストでありますが、内部の実装が異なります。LinkedList の各要素は、前の要素と次の要素のリンクを持ち、要素同士を前後双方向で参照する方法で配列要素を管理します。
上述のように、内部の作りはやや複雑ですが、使用方法は ArrayList とほぼ同じです。
LinkedList<String> linkedLIst = new LinkedList<>();
//要素の追加
linkedLIst.add("Java");
linkedLIst.add("Ruby");
linkedLIst.add("Python");
//要素の削除(2番目の要素の Ruby を削除)
linkedLIst.remove(1);
java.util.Set
Setインターフェイスを実装したクラスは、重複した要素を格納できないコレクションです。List インターフェイスでは追加した順序が保証されていましたが、Set インターフェイスを実装したコレクションクラスは、基本的には要素の追加順を保証しません。
この Set インターフェースを実装したコレクションクラスの代表例は、HashSet クラスです。
HashSet
HashSet クラスは、重複した要素が格納できず、追加した順序も保証しないコレクションクラスで、数学の集合に似た構造と考えて良いでしょう。
HashSet の初期化は次のように行います。
Set<String> hashSet = new HashSet<String>()
初期化時に要素を指定する場合は、次のようにします。
Set<String> hashSet = new HashSet(Arrays.asList("Java", "Ruby", "Python"));
また別の方法として、Java9 で追加された Set インターフェースの of メソッドを使って Set の初期化をすることができます。
ただし、この方法で初期化された Set のインスタンスは、読み取り専用となり、変更不可になります。
Set<String> hs = Set.of("Java", "Ruby", "Python");
同じキーが、すでにHashSet クラスに格納されているか調べる場合は、contains メソッドを使用して調べます。
if (hashSet.contains("Java")) {
System.out.println("セットにJavaは含まれます。");
}
java.util.Map
Mapインターフェースは、「キー」と「値」のペアを複数格納するためのインターフェイスです。Set インターフェースと同様に重複した「キー」を格納できないコレクションである。
この Map インターフェースを実装したコレクションクラスの代表例は、HashMap、LinkedHashMap クラスです。
HashMap
HashMap クラスは、Mapインターフェースを実装したクラスで、「キー」と「値」のペアを管理します。同じキーの値は1つしかもてず、コレクション内の順序は保証されません。
HashSet の初期化は次のように行います。
Map<String, Integer> hashMap = new HashMap<String, Integer>()
初期化時に要素を指定する場合は、次のように記述します。
Map<String, String> myMap = new HashMap<>() {{
put("apple", 100);
put("orange", 120);
put("grape", 130);
}};
初期化後に要素を追加する時は put メソッドを使用します。
hashMap.put("apple", 100);
hashMap.put("orange", 120);
hashMap.put("grape", 130);
LinkedHashMap
LinkedHashMap は重複した「キー」の「値」を保持できない点は HashMap と同じですが、要素を追加した順番が保証される点が HashMap と異なります。クラスの使用方法は HashMap とほぼ同じです。
まとめ
Java のコレクションである「List」「Set」「Map」の3つのインターフェースについて解説してきました。今回紹介したコレクションクラスは現場でも非常によく使うクラスですので是非覚えておきましょう。
LinkedList は配列内部の要素を順序ではなくリンク参照として管理しているため、インデックスを指定して要素を取得する場合は ArrayList より性能面で劣ります。
その反面、要素の追加と削除は、前後の要素のリンクを付け替えるだけでよいため、ArrayList よりも高速に行える場合があります。