はじめに (乱数と簡易グラフでJavaの基礎を学ぶ)

この記事は、Javaプログラミングの基礎を学び始めたばかりの方や、乱数を使ったちょっとしたデータ処理・可視化に興味がある方を対象にしています。

この記事を読むことで、Javaにおける乱数(ランダムな数値)の生成方法から、生成された数値の出現回数を効率的にカウントする方法、そしてその結果をアスタリスク(*)を使ったシンプルなテキストグラフとして表示する方法を、具体的なコードを交えて学ぶことができます。これにより、Javaの基本的なデータ構造(配列)や制御フロー(ループ、条件分岐)を実践的に使いこなすスキルが身につきます。プログラミングの面白さを、身近なデータ処理を通じて体験できるでしょう。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。 - Javaの基本的な文法(変数、データ型、算術演算子) - forループやif文などの基本的な制御構文 - Java開発環境(JDKとIDE、例: IntelliJ IDEA, Eclipse, VS Codeなど)がセットアップされていること

Java乱数生成とカウントの考え方

プログラミングにおいて「乱数」は、ゲームのキャラクターの動き、シミュレーション、パスワード生成など、様々な場面で活用される非常に重要な要素です。Javaでは、java.util.Randomクラスを使用することで、簡単に乱数を生成することができます。

今回の課題は、0から9までの整数を100個ランダムに生成し、それぞれの数字が何回出現したかを数え、その結果をアスタリスクで視覚的に表現するというものです。これは、一見するとシンプルな課題ですが、Javaの基本的な要素である「乱数生成」「配列」「ループ処理」「出力」を効果的に組み合わせることで解決できます。

なぜこの課題がプログラミング学習に適しているのでしょうか? 1. 実用的なスキル: 乱数生成は多くのアプリケーションで使われる基本的な機能です。 2. データ構造の理解: 出現回数を効率的に記録するためには、配列というデータ構造の理解が不可欠です。どのインデックスにどの数字のカウントを格納するか、という設計思考が養われます。 3. アルゴリズム的思考: 乱数を生成し、カウントし、表示するという一連の処理の流れをどのように組み立てるか、というアルゴリズム的思考力が鍛えられます。 4. 結果の視覚化: 単に数字を羅列するだけでなく、アスタリスクを使って簡易的なグラフとして表示することで、データの傾向を直感的に捉える練習にもなります。これは、より高度なデータ分析や可視化の基礎となる考え方です。

このセクションでは、まずこれらの要素をどのようにコードに落とし込むか、その全体的な考え方を説明しました。次のセクションでは、具体的な実装手順とコードを見ていきましょう。

Javaで100個の乱数分布をアスタリスク表示する

ここからは、実際にJavaコードを記述して、乱数生成から出現回数のアスタリスク表示までを実装していきます。ステップバイステップで進めていきましょう。

ステップ1: プロジェクトの作成と準備

まず、新しいJavaプロジェクトを作成し、メインクラスを用意します。 今回は「RandomHistogram」というプロジェクト名で進めます。

Java
// RandomHistogram.java public class RandomHistogram { public static void main(String[] args) { // ここにコードを記述していきます } }

ステップ2: 乱数生成と出現回数のカウント

次に、0から9の乱数を100個生成し、それぞれの数字の出現回数を記録する部分を作成します。ここでは配列を使用します。

  1. Randomオブジェクトのインスタンス化: java.util.Randomクラスを使って乱数を生成するための準備をします。
  2. 出現回数を記録する配列の宣言: 0から9までの数字の出現回数を記録するため、サイズ10の整数型配列を用意します。配列のインデックスがそのまま数字に対応するようにします(例: counts[0]が0の出現回数、counts[1]が1の出現回数)。
  3. 100回ループし、乱数を生成・カウント: forループを使って100回処理を繰り返します。各繰り返しで乱数を生成し、その乱数に対応する配列の要素をインクリメント(1増やす)します。
Java
import java.util.Random; // Randomクラスを使用するためにインポート public class RandomHistogram { public static void main(String[] args) { // 1. Randomオブジェクトのインスタンス化 Random random = new Random(); // 2. 出現回数を記録する配列の宣言と初期化 // インデックス0から9までを0-9の数字に対応させる int[] counts = new int[10]; // サイズ10の配列を作成。要素は自動的に0で初期化される // 3. 100回ループし、乱数を生成・カウント System.out.println("--- 乱数生成とカウント開始 ---"); for (int i = 0; i < 100; i++) { // 0から9までの乱数を生成 (nextInt(10)は0以上10未満の整数を返す) int randomNumber = random.nextInt(10); // 生成された乱数に対応する配列の要素をインクリメント counts[randomNumber]++; // 例えば、randomNumberが3ならcounts[3]が1増える } System.out.println("--- 乱数生成とカウント完了 ---"); // ここまでの動作確認として、カウント結果を一度表示してみる(オプション) // for (int i = 0; i < counts.length; i++) { // System.out.println(i + ": " + counts[i] + "回"); // } } }

ステップ3: 出現回数をアスタリスクで表示

最後に、counts配列に記録された出現回数をもとに、アスタリスクで簡易的なグラフを表示します。

  1. 配列の内容を順番に処理: forループを使って、0から9までの各数字について処理します。
  2. 数字と出現回数の表示: まず、現在の数字(インデックス)を表示します。
  3. アスタリスクの繰り返し表示: その数字の出現回数分だけアスタリスクを繰り返し表示します。これは、入れ子のforループを使うか、Java 11以降であればString.repeat()メソッドを使うと簡潔に書けます。
Java
import java.util.Random; public class RandomHistogram { public static void main(String[] args) { Random random = new Random(); int[] counts = new int[10]; System.out.println("--- 乱数生成とカウント開始 ---"); for (int i = 0; i < 100; i++) { int randomNumber = random.nextInt(10); counts[randomNumber]++; } System.out.println("--- 乱数生成とカウント完了 ---"); System.out.println("\n--- 出現回数ヒストグラム ---"); // 出現回数をアスタリスクで表示 for (int i = 0; i < counts.length; i++) { System.out.print(i + ": "); // 数字を表示 (例: "0: ") // その数字の出現回数分だけアスタリスクを表示 // Java 11以降の場合 // System.out.println("*".repeat(counts[i])); // Java 8などの古いバージョンや、より汎用的な方法 for (int j = 0; j < counts[i]; j++) { System.out.print("*"); } System.out.println(" (" + counts[i] + "回)"); // 出現回数を括弧で表示 } System.out.println("-------------------------"); } }

実行結果例(実行ごとに結果は変わります):

--- 乱数生成とカウント開始 ---
--- 乱数生成とカウント完了 ---

--- 出現回数ヒストグラム ---
0: ******** (8回)
1: ********* (9回)
2: ********* (9回)
3: ********* (9回)
4: ********** (10回)
5: *********** (11回)
6: ********* (9回)
7: *********** (11回)
8: ********** (10回)
9: ********* (9回)
-------------------------

この結果を見ると、乱数が均等に分散している様子が視覚的にわかります。

ハマった点やエラー解決

実装中に遭遇しがちな問題とその解決策について説明します。

  1. 乱数の範囲が意図と異なる:
    • random.nextInt(int bound)メソッドは、0(含む)からbound(含まない)までの整数を返します。したがって、0から9までの乱数を生成したい場合は、random.nextInt(10)を使う必要があります。
    • もし1から10までの乱数にしたい場合は、random.nextInt(10) + 1のように調整が必要です。
  2. ArrayIndexOutOfBoundsException(配列のインデックス範囲外エラー):
    • これは、存在しない配列のインデックスにアクセスしようとしたときに発生するエラーです。
    • 今回のケースでは、int[] counts = new int[10]; でサイズ10の配列を作成した場合、有効なインデックスは0から9までです。
    • もしrandom.nextInt()の引数を間違えて11にしてしまうと、10という乱数が生成される可能性があり、counts[10]にアクセスしようとしてエラーになります。
    • 常に乱数の生成範囲と配列のサイズ・インデックス範囲が一致しているかを確認しましょう。

解決策

  • 乱数の範囲:
    • int randomNumber = random.nextInt(10); を使用し、必ず0以上9以下の乱数が生成されるようにする。
  • 配列のインデックス範囲:
    • 配列のサイズを乱数の最大値(今回の場合は9)+ 1(0のインデックス分)に設定する。つまり、new int[10]が正しいです。
    • ループの条件式(for (int i = 0; i < counts.length; i++))が配列の有効な範囲内にあることを常に確認する。

これらの点に注意することで、スムーズにプログラムを動作させることができます。

まとめ

本記事では、Javaを使用して0から9までの乱数を100個生成し、それぞれの数字の出現回数をカウントして、アスタリスク(*)による簡易的なヒストグラムとして表示する方法を解説しました。

  • 要点1: java.util.RandomクラスのnextInt()メソッドを使って、指定範囲の乱数を生成する方法を学びました。
  • 要点2: 配列(int[])を使い、インデックスを数字に、要素を出現回数に対応させることで、効率的にデータをカウントできることを理解しました。
  • 要点3: forループを組み合わせることで、生成された乱数を処理し、最終的なカウント結果をアスタリスクで視覚的に表現する方法を実装しました。

この記事を通して、Javaの基本的な制御構造(ループ、配列)とRandomクラスの使い方を組み合わせることで、簡単なデータ処理と視覚化が実現できることを体験し、プログラミングの基礎的なスキルを向上させることができたでしょう。

今後は、乱数の生成範囲を可変にしたり、出現回数をより詳細な統計情報として表示したり(例: 割合表示)、さらにはJavaのGUIライブラリ(SwingやJavaFX)を使って本格的なグラフィカルなヒストグラムを作成したりすることにも挑戦してみてください。

参考資料