Arrays クラスの全体像をざっくりつかむ
java.util.Arrays は、
「配列を扱うときの“便利道具”をまとめたユーティリティクラス」です。
配列は int[], String[] などのあれです。
配列を
文字列としてきれいに表示したい
ソート(並び替え)したい
コピーしたい
検索したい
こういう「配列あるある作業」を、自分で for 文ゴリゴリ書かなくても済むようにしてくれるのが Arrays クラスです。
全部 static メソッドなので、インスタンスは作りません。Arrays.sort(...), Arrays.toString(...) のように、クラス名から直接呼びます。
toString / deepToString:配列の中身をきちんと表示する
普通に配列を println すると、変な表示になる理由
まず、配列をそのまま表示してみます。
int[] nums = {1, 2, 3};
System.out.println(nums);
Javaよく見ると、こんな感じが出ます。
[I@5a07e868
「何これ?」という値になります。
これは「配列オブジェクトの型情報+ハッシュコード」であって、中身ではありません。
配列の 中身 をちゃんと見たいときに使うのが Arrays.toString です。
toString で 1次元配列を読みやすくする
import java.util.Arrays;
int[] nums = {1, 2, 3};
System.out.println(Arrays.toString(nums)); // [1, 2, 3]
Java配列を [1, 2, 3] のような形で表示してくれます。
デバッグやログ出力で、これを知っているかどうかで快適さが全然違います。
String[] でも同じです。
String[] names = {"Alice", "Bob", "Carol"};
System.out.println(Arrays.toString(names)); // [Alice, Bob, Carol]
JavadeepToString で多次元配列(配列の配列)を表示
2次元配列など「配列の中に配列が入っている」場合は toString だと不十分です。
int[][] matrix = {
{1, 2},
{3, 4}
};
System.out.println(Arrays.toString(matrix)); // 中身がよく分からない
System.out.println(Arrays.deepToString(matrix)); // [[1, 2], [3, 4]]
JavadeepToString は、配列の中にさらに配列があっても、「中まで潜って」きちんと表示してくれます。
sort / binarySearch:並び替えと検索(ここはよく使う)
sort で配列を昇順にソートする
配列のソートはほぼ必ず Arrays.sort を使います。
int[] nums = { 5, 2, 9, 1, 3 };
Arrays.sort(nums); // 昇順に並び替え
System.out.println(Arrays.toString(nums)); // [1, 2, 3, 5, 9]
Javaint, long, double, char などのプリミティブ配列String[] や Integer[] などのオブジェクト配列
どちらにも使えます。
String[] の場合は辞書順(アルファベット順)になります。
String[] names = {"Bob", "Alice", "Carol"};
Arrays.sort(names);
System.out.println(Arrays.toString(names)); // [Alice, Bob, Carol]
Java独自の順番でソートしたいとき(初心者は「そういうのもある」程度で)
オブジェクト配列の場合、Comparator を渡して独自ルールでソートすることもできます。
String[] names = {"Bob", "Alice", "Carol"};
// 文字列の長さでソート(短い順)
Arrays.sort(names, (a, b) -> Integer.compare(a.length(), b.length()));
System.out.println(Arrays.toString(names)); // [Bob, Alice, Carol]
Java少し難しいですが、「ソートのルールを自分で決められる」と覚えておくと、
もう一歩踏み込んだときに役立ちます。
binarySearch でソート済み配列から効率よく探す
binarySearch は「ソート済み配列」に対して使う高速な検索メソッドです。
int[] nums = {1, 3, 5, 7, 9};
int index = Arrays.binarySearch(nums, 5);
System.out.println(index); // 2(nums[2] が 5)
Java注意点として、「配列がソートされていること」が前提です。
ソートされていない配列に対して使うと、正しい結果になりません。
見つからなかった場合は、負の値が返ってきます。
初心者のうちは、
「0 以上なら、そのインデックスで見つかった」
「負の値なら、見つからなかった」
くらいを覚えておけば十分です。
copyOf / copyOfRange / fill:配列のコピーや初期化
copyOf で配列を丸ごとコピー(長さ変更もできる)
int[] nums = {1, 2, 3};
int[] copy = Arrays.copyOf(nums, nums.length); // 同じ長さでコピー
System.out.println(Arrays.toString(copy)); // [1, 2, 3]
Java第2引数に「新しい配列の長さ」を渡せるので、長さを変えつつコピーもできます。
int[] nums = {1, 2, 3};
int[] bigger = Arrays.copyOf(nums, 5);
System.out.println(Arrays.toString(bigger)); // [1, 2, 3, 0, 0]
Java元の長さを超えた部分は、型のデフォルト値(int なら 0)で埋まります。
copyOfRange で一部分だけ切り出す
int[] nums = {10, 20, 30, 40, 50};
// index 1 〜 3(4 は含まない)をコピー
int[] part = Arrays.copyOfRange(nums, 1, 4);
System.out.println(Arrays.toString(part)); // [20, 30, 40]
JavafromIndex(含む)から toIndex(含まない)まで、というお約束です。String.substring と同じイメージです。
fill で全要素を同じ値で埋める
int[] nums = new int[5];
Arrays.fill(nums, 7); // すべて 7 で埋める
System.out.println(Arrays.toString(nums)); // [7, 7, 7, 7, 7]
Java「初期値が全部同じ」の配列を作りたいときに便利です。
equals / deepEquals:配列同士をちゃんと比較する
配列同士の == は「中身の比較」にならない
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a == b); // false
Java== は「同じ配列オブジェクトかどうか(参照比較)」なので、中身は見てくれません。
「中身が同じかどうか」を比較したいときに Arrays.equals を使います。
System.out.println(Arrays.equals(a, b)); // true(要素がすべて等しい)
Java要素数・各要素がすべて等しければ true です。
多次元配列なら deepEquals
配列の中に配列がある場合も、普通の equals では足りません。
int[][] x = {{1, 2}, {3, 4}};
int[][] y = {{1, 2}, {3, 4}};
System.out.println(Arrays.equals(x, y)); // false(参照の配列だけ比較)
System.out.println(Arrays.deepEquals(x, y)); // true(中まで潜って比較)
Java2次元以上の配列を比較したいときは、deepEquals を使うのが鉄板パターンです。
まとめ:Arrays クラスをどう自分の“標準装備”にするか
初心者向けに、Arrays クラスをこう整理しておくと使いやすくなります。
配列の中身をデバッグ表示したい → Arrays.toString / Arrays.deepToString
配列の並び替え → Arrays.sort
ソート済み配列から効率よく検索 → Arrays.binarySearch
配列をコピーしたい → Arrays.copyOf / Arrays.copyOfRange
配列を同じ値で初期化 → Arrays.fill
配列同士の中身の比較 → Arrays.equals / Arrays.deepEquals
どれも「自分で for 文を書くことはできるけど、毎回書きたくない処理」を
一発でやってくれるものばかりです。
