Collections クラスの全体像をざっくりつかむ
java.util.Collections は、
「List や Map など“コレクション”を扱うときの便利メソッドを集めたユーティリティクラス」
です。
Arrays クラスが「配列専用の便利道具」だったのに対して、Collections は「List・Set・Map などコレクション全般の便利道具」がまとまっています。
すべて static メソッドなので、new Collections() はしません。Collections.sort(...)、Collections.shuffle(...) のようにクラス名から直接呼びます。
やることのイメージはだいたい次のような感じです。
- コレクションを並び替える(sort)
- シャッフルする(shuffle)
- 最小値・最大値を求める(min / max)
- 要素を一括で埋める(fill)
- 変更禁止のコレクションを作る(unmodifiable 系)
このあたりを押さえれば、「Collections クラスって何者か」がぐっとクリアになります。
sort:List を並び替える(Arrays.sort のコレクション版)
基本:List を自然順(昇順)にソートする
まずは一番よく使う Collections.sort から説明します。
import java.util.*;
public class CollectionsSortBasic {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(5);
list.add(2);
list.add(9);
list.add(1);
Collections.sort(list); // 昇順に並び替え
System.out.println(list); // [1, 2, 5, 9]
}
}
JavaArrays.sort が「配列をその場で並び替え」ていたように、Collections.sort も「List をその場で並び替え」ます。
ポイントは、List は int[] のような配列ではなく、List<Integer> のような「オブジェクトの集合」です。
つまり、Collections.sort の対象は
List<T>(多くは ArrayList や LinkedList)
と覚えてください。
文字列の List も同様です。
List<String> names = new ArrayList<>();
names.add("Bob");
names.add("Alice");
names.add("Carol");
Collections.sort(names); // 辞書順
System.out.println(names); // [Alice, Bob, Carol]
Javaここで重要なのは、Collections.sort は「インデックスで順番を持つコレクション(List)」専用だということです。Set はそもそも順番を保証しないので、Collections.sort(set) とは書けません。
shuffle:List の順番をランダムに入れ替える
ランダムな並び順を作りたいときの定番
カードゲームのデッキをシャッフルするようなイメージで、
List の要素の順番をランダムに入れ替えるのが Collections.shuffle です。
import java.util.*;
public class CollectionsShuffleBasic {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
list.add(i);
}
System.out.println("before: " + list);
Collections.shuffle(list);
System.out.println("after : " + list);
}
}
Java実行するたびに after の並びが変わります。
ゲームのカード、ガチャの候補、ランダム表示など、
「順番だけランダムにしたい」ときに極めてよく使います。
内部では Random を使っているので、シード付きの Random を使いたい場合はCollections.shuffle(list, random) のように、Random を渡すオーバーロードも使えます。
min / max:List の中の最小値・最大値を取る
Collections.min / Collections.max の基本的な使い方
「この List の中で一番小さい(大きい)要素はどれ?」
こういう処理を、自分でループを書かずに一発でやってくれるのが Collections.min / Collections.max です。
import java.util.*;
public class CollectionsMinMax {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(5, 2, 9, 1, 3);
int min = Collections.min(list);
int max = Collections.max(list);
System.out.println("min = " + min); // 1
System.out.println("max = " + max); // 9
}
}
JavaInteger, String など「自然な順序(Comparable を実装している)」型であれば、そのまま使えます。
文字列なら辞書順で最小・最大が決まります。
min / max も、sort と同じく List が前提です。
配列が相手なら、まず Arrays.asList(array) で List に変換する、
あるいは配列のまま自分でループを書く、といった選択になります。
fill / nCopies:同じ値で埋める、同じ値だけの List を作る
fill:既存の List を同じ要素で埋める
Collections.fill は、List の全要素を同じ値で上書きします。
import java.util.*;
public class CollectionsFill {
public static void main(String[] args) {
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Collections.fill(list, "X");
System.out.println(list); // [X, X, X]
}
}
Java注意点として、「要素数が増えるわけではない」ことです。
既にある各位置に、同じ値をセットし直している、というイメージです。
nCopies:同じ要素を N 個持つ「読み取り専用 List」を作る
「同じ値を N 回分持つ List」が欲しいときは、Collections.nCopies が使えます。
import java.util.*;
public class CollectionsNCopies {
public static void main(String[] args) {
List<String> list = Collections.nCopies(5, "hello");
System.out.println(list); // [hello, hello, hello, hello, hello]
}
}
Javaここで返ってくる List は「読み取り専用」です。add や set を行うと UnsupportedOperationException が投げられます。
「定数的な List をひとまず作りたい」
「テスト用に、同じ値ばかりの List が欲しい」
といった用途に向いています。
unmodifiableXxx:変更禁止のコレクションを作る意味
unmodifiableList / unmodifiableSet / unmodifiableMap の役割
Collections.unmodifiableList(list) は、
「この List を“読み取り専用ビュー”として外に渡したい」
ときに使います。
import java.util.*;
public class CollectionsUnmodifiable {
public static void main(String[] args) {
List<String> modifiable = new ArrayList<>();
modifiable.add("A");
modifiable.add("B");
List<String> readOnly = Collections.unmodifiableList(modifiable);
System.out.println(readOnly); // [A, B]
readOnly.add("C"); // UnsupportedOperationException
}
}
JavareadOnly は add や remove をしようとすると例外になりますが、modifiable 側を変えると、その変更は readOnly にも見えます。
「中身を完全コピーしている」のではなく、「元の List を変更不可として見せているビュー」と捉えると分かりやすいです。
なぜこんなことをするかというと、
「このメソッドは List を返すけど、その List を呼び出し側から勝手に書き換えられたくない」
という設計のときに便利だからです。
class UserListHolder {
private final List<String> users = new ArrayList<>();
public List<String> getUsers() {
return Collections.unmodifiableList(users);
}
}
Javaこのようにしておくと、getUsers() を受け取った側がうっかり add しても例外になり、
「勝手に裏の状態を変えられて壊される」ことを防げます。
その他よく出てくるユーティリティ(frequency / reverse など)
frequency:特定の要素が何回現れるかを数える
import java.util.*;
public class CollectionsFrequency {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "a", "c", "a");
int count = Collections.frequency(list, "a");
System.out.println(count); // 3
}
}
Java「指定した要素が List の中に何個あるか」がパッとわかります。
集計系の軽い処理で便利です。
reverse:List の順番を逆にする
import java.util.*;
public class CollectionsReverse {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
Collections.reverse(list);
System.out.println(list); // [4, 3, 2, 1]
}
}
Javaこれは単純に、「前後をひっくり返す」処理です。
昇順にソートした後に reverse して降順にする、というテクニックもよくあります。
まとめ:Collections クラスをどう自分の「標準装備」にするか
Collections クラスを初心者向けに一言でまとめると、
「List(などのコレクション)に対する “よくある操作” を一発でやってくれる便利メソッド集」
です。
特に意識してほしいのは次のようなところです。
- List を並び替え →
Collections.sort - List をランダムにシャッフル →
Collections.shuffle - List の中の最小値・最大値 →
Collections.min/Collections.max - List の全要素を同じ値で埋める →
Collections.fill - 同じ要素 N 個の読み取り専用 List →
Collections.nCopies - 外に渡すときに変更禁止にしたい →
Collections.unmodifiableList(Set / Map も同様にある)
