🐷

Java コレクションフレームワーク(List、Map、Set)

2024/12/10に公開

Java コレクションフレームワーク

コレクション

・複数の要素のまとまりのこと。
・用途の異なるコレクションが存在する(List、Map、Set)。
・配列とは異なり、要素数を自由に増減させることができる。
・「クラス名<型指定>」の書式で指定した型専用のオブジェクトを作成できる。
・コレクションには次のような種類が存在する。

コレクションの種類 特徴
List(java.util.List) 要素が順序付けられて保持される。重複できる。
Map(java.util.Map) キーと値を紐づけて要素が保持される。同じキーの重複はできない。同じキーがセット(put)された場合は上書きされる。
Set(java.util.Set) 要素が重複しない、要素が順序付けられていない。Listのような順番付けや、Mapのようなキー管理もない。同じキーがセット(add)された場合は上書きされる。

・List,Map,Set 自体はインターフェースという抽象的なもの。List,Map,Set はあくまでもインタフェースであるため、インスタンスの生成はできない。

//[間違い]Map<String, String> map = new Map<String, String>();

・List,Map,Set にはそれぞれさらに種類がある。
・Listの1つがArrayList。
・ArrayListは順番が保証される。eachで順番に取り出しを毎回実行しても、順番は常に同じ。
・あらかじめ要素数が想定される場合はサイズ宣言できる。

var data = new ArrayList<String>(30);

・Mapの1つがHashMap。IDと会員の紐づけなどでよく利用される。
・MapはCollectionインターフェースを継承してない(マップをそのまま拡張forに渡せない)

[Map]
HashMap
IdentityHashMap
WeakHashMap
LinkedHashMap
TreeMap
HashTable(HashMapを優先)

[[ Map使用例 ]]

import java.util.HashMap;
import java.util.Map;

public class Main {
  public static void main(String[] args) {
	var map = new HashMap<String, String>(Map.of("Cat", "ねこ",
  	"Dog", "いぬ", "Bird", "とり"));
	//指定キーが含まれるか
	System.out.println(map.containsKey("Dog")); //true
	//指定値が含まれるか
	System.out.println(map.containsValue("ねこ")); //true
	//マップが空か
	System.out.println(map.isEmpty()); //false
	//全キー取得
	for (var key : map.keySet()) {
  	System.out.println(key); //Dog Bird Cat
	}
	//全値取得
	for (var value : map.values()) {
  	System.out.println(value); //いぬ とり ねこ
	}
	//指定キーの値をvalueに変更
	map.replace("Cat", "neko");
	//指定キーの値/値(old)をvalue(new)に変更
	map.replace("Bird", "とり", "tori");
	//全ての要素取得
	for (var entry : map.entrySet()) {
  	System.out.println(entry.getKey() + ":" + entry.getValue()); //Dog:いぬ Bird:tori Cat:neko
	}
  }
}

・HashMapは順番が保証されない。そのため、eachで順番に取り出しを毎回実行すると、その都度、順番が入れ替わる。
・MapコレクションにはHashMap以外にもいろいろある。例えば、HashSetとTreeSetの違いは下記の通り。

[Map] TreeSet HashSet
null 格納不可 格納可
ソート 自動でする しない

・HashMapはMapインタフェースを実装したコレクションクラス。HashMapはクラスなのでインスタンスを生成できる。

//初期化
HashMap<Integer,String> humanMap = new HashMap<Integer,String>();
//検索
humanMap .get(1); //なければnullが返る
//要素追加(キー、値)
humanMap .put(2, "value2");
//要素削除
humanMap .remove(3);
カテゴリ クラス 説明
List系 ArrayList 配列を扱う。
LinkedList 配列を扱う。挿入・削除が高速。
Vector 配列を扱う。パフォーマンスが悪いため現在ではあまり推奨されない古いクラス。
Set系 HashSet 値の重複を許さない順不同の要素集合を扱う。
TreeSet 値の重複を許さないソートされた要素集合を扱う。
Map系 HashMap キーと値の組からなる要素の集合を扱う。
LinkedHashMap キーと値の組からなる要素の集合を扱う。設定順序が保証される。
TreeMap キーと値の組からなる要素の集合を扱う。キーでソートされてる。
Queue系 Deque キューやスタックを扱う。

コレクションクラスの比較

コレクションクラスには大きく分けてList、Map、Setの3種類がある。
そして、さらに性質の異なるクラスに分かれている。
各コレクションクラスの特徴は以下の通り。

[Javaコレクションフレームワーク] ArrayList LinkedList HashMap TreeMap HashSet TreeSet
インターフェイス List List Map Map Set Set
要素の重複 × × × ×
null値の要素 × ×
自動ソート × × × ×

List
順番を保持した動的配列で、以下の特徴がある。

  • 格納した順番も保持される。
  • インデックス番号を指定して特定のデータを取得することが出来る。
  • データの重複が可能。

Listの種類

クラス名 説明
ArrayList 要素へのアクセススピードが速い。要素の追加・削除は遅い。
LinkedList 要素へのアクセススピードが遅い。要素の追加・削除は速い。

Listの主なメソッド
メソッドの引数や戻り値にあるEは総称型といい、Listに格納できるデータの型を指定しているもので、Listの宣言時に指定する。

メソッド名 説明
boolean add(E e) Listの最後尾に新しい要素を追加する。
E get(int index) 引数に指定したインデックス番号の要素を取り出す。
int size() Listに格納されている要素の数を返す。
boolean isEmpty() Listが空かどうか確認する。Listの要素数が0の場合true、0でない場合falseを返す。
void clear() Listの要素を全て削除する。
public class Sample {
    public void listSample(){
        List<String> list = new ArrayList<>();
        list.add("りんご");
        list.add("ぶどう");
        list.add("ばなな");
        list.add("ぶどう");

        list.isEmpty(); // false
        list.size(); // 4
        String s = list.get(0); // りんご
        String s = list.get(1); // ぶどう
        String s = list.get(2); // ばなな
        String s = list.get(3); // ぶどう
        list.clear();
        list.isEmpty(); // true
        list.size(); // 0
    }
}

変更不可List

String型の変数の場合、以下のように記述することで変数の値を変更することができなくなる。

final Stirng moji = "あいうえお";

同じような記述をListで書いた場合、別のListを代入することはできないが、今変数に代入されているListに対して値を追加することはできてしまう。

List<String> list = new ArrayList<>();
list.add("りんご");
final List<String> myList = list;

// これはできない
myList = new new ArrayList<String>();

// これはできる
myList.add("ごりら");

Listに格納されている値の数や内容を変更されたくない場合は、unmodifiableListとする必要がある。

final List<Integer> val1 = Arrays.asList(1003, 1002, 1003, 1001, 1002);
final List<String> val2 = Collections.unmodifiableList(Arrays.asList("2023-02-08", "2023-02-08", "2023-02-09", "2023-02-09", "2023-02-10"));	
final List<String> val3 = Collections.unmodifiableList(Arrays.asList("昨日の夜は徹夜でした・・	", "お疲れ様です!", "今日も頑張ります!", "無理は禁物ですよ!", "明日から連休ですね!"));
final List<Integer> val4 = Arrays.asList(13, 12, 18, 17, 20);

Set

以下の特徴がある。

  • 格納した順番は保持しない
  • データの重複が出来ない

Setの種類

クラス名 説明
HashSet 要素の順番を保持しない。データの重複は出来ない。
LinkedHashSet 要素の順番を保持する。データの重複は出来ない。
TreeSet 要素の順番はソートされる。データの重複は出来ない。

Setの主なメソッド
メソッドの引数や戻り値にあるEは総称型と言い、Setに格納できるデータの型を指定しているもので、Setの宣言時に指定する。

メソッド名 説明
boolean add(E e) Set に新しい要素を追加する。追加しようとしたデータがまだ存在していなかった場合 true を返す。
int size() Setに格納されている要素の数を返す。
boolean isEmpty() Set が 空 かどうか確認する。 Set の要素数が 0 の場合 true 、 0 でない場合 false を返す。
void clear() Set の要素を全て削除する。
public class Sample {
    public void setSample(){
        Set<String> set = new HashSet<>();
        set.add("りんご");
        set.add("ぶどう");
        set.add("ばなな");

        set.isEmpty(); // false
        set.size(); // 3
        for(String s : set) {
            System.out.println(s); // 順番は保持していないので出てくる順番はランダムとなる
        }
        set.clear();
        set.isEmpty(); // true
        set.size(); // 0
    }
}

変更不可Set
Collections#unmodifiableSetメソッドを使用して既存の Set を 変更不可Set にするか、 Set#ofメソッド で最初から 変更不可Set を作成する。

Set<String> set = new HashSet<>();
set.add("りんご");
Set<String> mySet = Collections.unmodifiableSet(set);

// Set#ofメソッドで作成したリストもunmodifiableSetとなる
Set<String> mySet = Set.of("りんご");

Map

別名、ハッシュテーブル、連想配列、ハッシュマップと呼ばれる。
データをkey-valueで対応付けている。

以下の特徴を持つ。

  • 格納した順番は保持しない
  • キーの重複が出来ない⇒同じkeyのデータを追加しようとした場合は上書きされる

Mapの種類

クラス名 説明
HashMap 要素の順番を保持しない。データの重複は出来ない。
LinkedHashMap 要素の順番を保持する。データの重複は出来ない。
TreeMap 要素の順番はキーでソートされる。データの重複は出来ない。

Mapの主なメソッド
メソッドの引数や戻り値にあるK, Vは総称型といい、Mapに格納できるデータの型を指定しているもので、Mapの宣言時に指定する。

メソッド名 説明
V put(K k, V v) Mapに新しい要素を追加する。追加したValueが返される。
V get(Object key) 引数にキーに対応するValueを取り出す。対応するものがない場合はnullを返す。
int size() Mapに格納されている要素の数を返す。
boolean isEmpty() Mapが空かどうか確認する。Mapの要素数が0の場合true、 0でない場合falseを返す。
Set<K> keySet() KeyのSetを返す。
Collection<V> values() ValueのCollectionを返す。
Set<Map.Entry<K, V>> entrySet() Mapに格納されているデータ(Entry)のSetを返す。
void clear() Mapの要素を全て削除する。
Map<String, String> map = new HashMap<>();
map.put("001", "花子");
map.put("002", "次郎");
map.put("003", "三郎");

map.isEmpty(); // false
map.size(); // 3
String name = map.get("001"); // 花子
String name = map.get("002"); // 次郎
String name = map.get("003"); // 三郎
String name = map.get("004"); // null

for(String key : map.keySet()) {
    System.out.println(key); // 順番は保持していないので出てくる順番はランダムとなる
}

for (Map.Entry<String, String> e : map.entrySet()) {
    System.out.println(e.getKey() + ":" + e.getValue());
}

map.clear();
map.isEmpty(); // true
map.size(); // 0

変更不可Map
Collections#unmodifiableMapメソッドを使用して既存のMapを変更不可Mapにするか、 Map#ofメソッドで最初から変更不可Mapを作成する。

Map<String, String> map = new HashMap<>();
map.put("apple", "りんご");
Map<String, String> myMap = Collections.unmodifiableMap(map);

// Map#ofメソッドで作成したリストもunmodifiableMapとなる
Map<String, String> myMap = Map.of("apple", "りんご");

[参考サイト]

https://qiita.com/suema0331/items/637ff9457a371069a7dc

Discussion