Java | Java 標準ライブラリ:Collections クラス

Java Java
スポンサーリンク

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]
    }
}
Java

Arrays.sort が「配列をその場で並び替え」ていたように、
Collections.sort も「List をその場で並び替え」ます。

ポイントは、List は int[] のような配列ではなく、List<Integer> のような「オブジェクトの集合」です。
つまり、Collections.sort の対象は

List<T>(多くは ArrayListLinkedList

と覚えてください。

文字列の 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
    }
}
Java

Integer, 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 は「読み取り専用」です。
addset を行うと 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
    }
}
Java

readOnlyaddremove をしようとすると例外になりますが、
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 も同様にある)

タイトルとURLをコピーしました