ここでは 実務でそのまま使えるレベルの「配列表示ユーティリティ」コード を提供します。
実務でよくある要件を満たしています:
✔ ログに大量データを丸ごと出さない(可読性確保)
✔ null 安全
✔ 1次元 / 多次元配列どちらも対応
✔ Java オブジェクトでも扱える
✔ 汎用メソッド名(toDebugString)
✔ ライブラリ不要(JDK 標準のみ)
実務レベル:配列・リストの中身を安全&見やすく表示するユーティリティ
以下は Array / Collection / Map / Object すべてに対して
「見やすい文字列表現」を返すメソッド群です。
import java.util.*;
import java.util.stream.Collectors;
public class DebugUtil {
/**
* 任意のオブジェクトを見やすく表示する。
* 配列は要素を展開、コレクションも展開。
* null 安全。
*/
public static String toDebugString(Object obj) {
if (obj == null) return "null";
Class<?> clazz = obj.getClass();
// -------- ① 配列 ----------
if (clazz.isArray()) {
// 多次元配列対応(deepToString)
return deepArrayToString(obj);
}
// -------- ② Collection(List、Set) ----------
if (obj instanceof Collection) {
Collection<?> col = (Collection<?>) obj;
return col.stream()
.map(DebugUtil::toDebugString)
.collect(Collectors.joining(", ", "[", "]"));
}
// -------- ③ Map ----------
if (obj instanceof Map) {
Map<?, ?> map = (Map<?, ?>) obj;
return map.entrySet().stream()
.map(e -> toDebugString(e.getKey()) + "=" + toDebugString(e.getValue()))
.collect(Collectors.joining(", ", "{", "}"));
}
// -------- ④ 配列でもコレクションでもない普通のオブジェクト ----------
return obj.toString();
}
/** 多次元配列も安全に文字列化するための内部メソッド */
private static String deepArrayToString(Object array) {
if (array == null) return "null";
// Object[] なら Arrays.deepToString が使える
if (array instanceof Object[]) {
return Arrays.deepToString((Object[]) array);
}
// プリミティブ配列の場合 個別に処理
if (array instanceof int[]) return Arrays.toString((int[]) array);
if (array instanceof long[]) return Arrays.toString((long[]) array);
if (array instanceof double[]) return Arrays.toString((double[]) array);
if (array instanceof float[]) return Arrays.toString((float[]) array);
if (array instanceof char[]) return Arrays.toString((char[]) array);
if (array instanceof short[]) return Arrays.toString((short[]) array);
if (array instanceof byte[]) return Arrays.toString((byte[]) array);
if (array instanceof boolean[])return Arrays.toString((boolean[]) array);
return "Unsupported array type";
}
}
Java実務での使い方例(main メソッド付き)
public class Main {
public static void main(String[] args) {
int[] a1 = {1, 2, 3};
int[][] a2 = {{10, 20}, {30, 40}};
List<String> fruits = Arrays.asList("apple", "banana", "orange");
Map<String, Integer> scores = Map.of("Alice", 90, "Bob", 80);
System.out.println(DebugUtil.toDebugString(a1));
System.out.println(DebugUtil.toDebugString(a2));
System.out.println(DebugUtil.toDebugString(fruits));
System.out.println(DebugUtil.toDebugString(scores));
}
}
Java期待される実行結果
(実務でログに出るイメージ)
[1, 2, 3]
[[10, 20], [30, 40]]
[apple, banana, orange]
{Alice=90, Bob=80}
実務でありがちな応用版:巨大配列の「途中までだけ」表示
ログが肥大化しないように 最大 N 件だけ表示 するバージョン。
public static String toDebugStringLimit(Object[] array, int limit) {
if (array == null) return "null";
int size = Math.min(array.length, limit);
return Arrays.stream(array)
.limit(size)
.map(DebugUtil::toDebugString)
.collect(Collectors.joining(", ", "[", (array.length > limit ? ", ...]" : "]")));
}
Java実務でよく受ける質問(FAQ)
Q. なぜ Arrays.deepToString だけではダメ?
- プリミティブ多次元配列(例:
int[][])はObject[]として扱うので OK - しかし 1 次元プリミティブ配列(
int[]など)を Object と混ぜる場面で型不一致が起こる - そのため上記のように個別に処理する方が安全
Q. ログで配列を全部出したくない
→ toDebugStringLimit を使う
(例:10件だけ表示して残りは “…”)
