Java Basic1 〜文字列操作(Stringクラス)の扱い

文字列の操作

1.1 文字列処理とは

ズバリ、文字列を切り貼りします

例:1.1 「文字列を切り取る」
「こんにちは世界」という文字列の"ちは"を切り取ると「こんに世界」になります。
コードで書くと下のようなコードになります。Javaのプログラムで実行する時には下のようなコードで実行します。あくまでもサンプルなのでやり方は自分で考えて作れるようにしたいですね。

処理の内容などは、これから学んでいきます。

/**
 * 文字列の操作。
 *
 */
public class StringControl {

    /**
     * 動かしたいメソッドを呼び出してやれば動かせます。
     * 例として「1.1文字列処理とは」のサンプルコードを呼び出しています。
     *
     * @param args
     */
    public static void main(String[] args) {
        StringControl main = new StringControl();
        main.substringTest();
    }

    /**
     * 「1.1.1文字列処理とは」のサンプルコード。
     * 文字列を切り取る処理のサンプル<br/>
     * <br/>
     * <b>「こんにちは世界」という文字列の"ちは"を切り取る</b>
     */
    public void substringTest() {
        // 変数の初期化
        String moji = "こんにちは世界";
        // *******************************************************//
        // * やり方1:Stringクラスのメソッド「substring()」を呼び出す *
        // *******************************************************//
        String rightStr = moji.substring(0, 3);
        String leftStr  = moji.substring(5, 7);
        System.out.println("切り取った結果1は「" + rightStr + leftStr + "」です。");

        // *******************************************************//
        // * やり方2:char型の配列を取り出してやる                   *
        // *******************************************************//
        char[] charMoji = moji.toCharArray();
        // 切り取った結果を格納する
        char[] resArray = new char[charMoji.length];
        int resCount = 0;
        for (int i = 0; i < charMoji.length; i++) {
            if (i != 3 && i != 4) {
                // 表示する文字を設定(セット)する
                resArray[resCount] = charMoji[i];
                resCount++;
            }
        }
        // char型の配列をStringとして生成
        String resString = new String(resArray);
        System.out.println("切り取った結果2は「" + resString + "」です。");
    }

    /**
     * 「1.2.1とは」のサンプルコード。
     * 文字列を調査するサンプル<br/>
     * <table>
     *     <thead>
     *         <tr><th>操作</th></tr></tr>
     *         <th>メソッド定義(シグニチャ)</th></tr>
     *     </thead>
     *     <tbody>
     *         <tr><td>内容が等しいか調べる</td></tr>
     *         <tr><td>public boolean equals(Object o)</td></tr>
     *     </tbody>
     * </table>
     */
    public void checkString() {

        String moji = "test";

        // String#equals()
        if (moji.equals("test")) {
            System.out.println("mojiは\"test\"です。");
        } else {
            System.out.println("mojiは\"test\"ではありません。");
        }

        // String#equalsIgnoreCase()
        if (moji.equalsIgnoreCase("Test")) {
            System.out.println("mojiは\"Test\" or \"Test\"です。");           
        } else {
            System.out.println("mojiは\"Test\" or \"Test\"ではありません。");          
        }

        // String#isEmpty()
        if (moji.isEmpty()) {
            System.out.println("mojiは\"\"です。");
        } else {
            System.out.println("mojiは\"\"ではありません。");
        }
    }
}

1.2 基本的な文字列操作

操作 メソッド定義(シグニチャ)
内容が等しいか調べる public boolean equals(Object o)
大文字小文字を区別せず内容が等しいか調べる public boolean equalsIgnoreCase(String s)
文字列長を調べる public int length()
空文字か調べる public boolean isEmpty()

Sample1 1-1 文字列調査メソッドを利用した例

※クラス全体ではなく、メソッド部分のみを記述します。

使用するメソッド一覧
String#equals()
String#equalsIgnoreCase()
String#isEmpty()

/**
 * 文字列調査(文字列が等しいか?)のサンプル。
 * 「リスト1-1 文字列調査メソッドを利用した例」
 */
public void sample1_1StringEquals() {
    // 文字列を比較した場合
    System.out.println("*** String#equals() Sample1 ****");
    if ("test".equals("tezt")) {
        System.out.println("\"test\"と\"tezt\"は等しいです。");
    } else if ("test".equals("tezt") == false) {
        System.out.println("\"test\"と\"tezt\"は等しくありません。");
    } else {
        // 実際は例外しか返ってこないので意味のないコード
        // 想定外のケースも考慮に入れる
        System.out.println("trueもfalseも帰ってこなかった場合。");
    }
    System.out.println("*** String#equals() Sample2 ****");
    // 変数に入れた文字列を比較した場合
    String str = "test";
    String str2 = "tezt";
    if (str.equals(str2)) {
        System.out.println("\"test\"と\"tezt\"は等しいです。");
    } else {
        System.out.println("\"test\"と\"tezt\"は等しくありません。");
    }
    System.out.println("*** String#equalsIgnoreCase() Sample1 ****");
    if ("test".equalsIgnoreCase("tezt")) {
        System.out.println("\"test\"と\"tezt\"は等しいです。");
    } else if ("test".equalsIgnoreCase("tezt") == false) {
        System.out.println("\"test\"と\"tezt\"は等しくありません。");
    } else if ("test".equalsIgnoreCase("Test")) {
        System.out.println("\"test\"と\"Test\"は等しいです。");
    } else {
        // 実際は例外しか返ってこないので意味のないコード
        // 想定外のケースも考慮に入れる
        System.out.println("trueもfalseも帰ってこなかった場合。");
    }

    System.out.println("*** String#isEmpty() Sample1 ****");
    if ("".isEmpty()) {
        System.out.println("文字列は空です。");
    }
    String tmp = null;

    System.out.println("*** String#isEmpty() Sample2 ****");
    try {
        if (tmp.isEmpty()) {
            System.out.println("文字列はNULLです。");
        }
    } catch (NullPointerException e) {
        System.out.println("実行するとNullPoineterExceptionで落ちる。");
    }
}

Sample1: 文字列の調査メソッドの解説

  1. "test".equals("tezt")は、"test"と"tezt"を比較している2つの文字列が等しいならifの中に処理が進む
  2. "test".equals("tezt") == falseは2つの文字列を比較した時の返り値がfalseの場合ifの中に処理が進む
  3. str.equals(str2)は変数「str」と「str2」を比較した時の返り値がtrueの場合ifの中に処理が進む
  4. "test".equalsIgnoreCase("tezt") == falseは下の内容の処理を行っているので「大文字小文字の区別無し」で文字列の比較した時の返り値がtrueの場合ifの中に処理が進む ※Stringクラスのソースファイル参照
    public boolean equalsIgnoreCase(String anotherString) {
    return (this == anotherString) ? true
            : (anotherString != null)
            && (anotherString.value.length == value.length)
            && regionMatches(true, 0, anotherString, 0, value.length);
    }
  5. "test".equalsIgnoreCase("Test")は"test"と"Test"を比較した時の返り値がtrueの場合ifの中に処理が進む
  6. "".isEmpty()は""が空文字だった場合ifの中に処理が進む
  7. String tmp = null;<code>は変数</code>tmpにNULLを代入している、この変数を参照するとNullPointerExceptionで落ちる
  8. try { 何かの処理 } catch ( キャッチする例外 ) { 例外時の処理 }で例外が起きた時の処理を行う。

Sample2 1-2 文字列検索メソッドを利用した例

※クラス全体ではなく、メソッド部分のみを記述します。

使用メソッド一覧
String#contains()
String#endsWith()
String#indexOf()

/**
 * 文字列調査(文字列が等しいか?)のサンプル。
 * 「リスト1-2 文字列検索メソッドを利用した例」
 */
public void sample1_2StringSearch() {
    String str = "0123456789ABCABC";
    System.out.println("*** String#contains() Sample1 ****");
    if (str.contains("012")) {
        System.out.println(str + "は「012」を含んでいます。");
    }
    System.out.println("*** String#contains() Sample1 ****");
    if (str.contains("014")) {
        System.out.println(str + "は「014」を含んでいます。");
    } else {
        System.out.println(str + "は「014」を含んでいません。");
    }

    System.out.println("*** String#endsWith() Sample1 ****");
    if (str.endsWith("ABC")) {
        System.out.println(str + "は「ABC」を末尾にあります。");
    }

    System.out.println("*** String#endsWith() Sample1 ****");
    System.out.println(str + "は「ABC」の文字列が" + str.indexOf("ABC") + "番目に出現します。");
    System.out.println(str + "は「ABC」の文字列が最後に出現するのは" + str.lastIndexOf("ABC") + "番目に出現します。");
}

文字列検索メソッドの解説

  1. str.contains("012")で文字列strに"012"が含まれているか検証しています。含まれているならばtrueを返します。そうでない場合はfalseを返す
  2. str.endsWith("ABC")で文字列strの末尾に"ABC"があるか検証しています。末尾にあればtrue, なければfalseを返す。
  3. str.indexOf("ABC")で文字列str内の"ABC"がはじめに出現する位置(int型)を返します。
  4. str.indexOf("ABC")で文字列str内の"ABC"が最後に出現する位置(int型)を返します。

正規表現を使う

上に記載したもの以外にも、よく使うメソッドを紹介します。

String#matchies()です。

このメソッドは、引数に正規表現を渡して、その正規表現にマッチするならtrue, そうでないならfalseを返します。

正規表現は後々に学習します。とりあえずは下の「数字」とaからz、AからZまでの文字にマッチするケースです。

チェック処理なので、静的メソッドにしています。

public static boolean isNumber(String numberStr) {
    // numberStr0から9のうちどれかに該当するか判定します。(1文字だけ)
    if (numberStr.matches("[0-9]")) {
        return true;
    }
    return false;
}

上の処理は、numberStrが数字1文字で、0から9に該当するかどうかの判定を行なっています。

文字数を複数にする場合は後ろに、「{2,5}」のようにつけると「2桁から5桁の間の0から9の数字」というような意味になります。

関連ページ

Java 練習問題集 ~基本レベル1の問題~

練習問題集(Training)

Javaコードの練習をします。ちょっとしたヒントもあるので頑張って解いてみてください。

Javaの文法を覚えたけど、以下のような思いがあるときに使ってください。

  • 本文の記載内容がわからない
  • まだしっくりこない
  • 基本をもっと理解したい
  • JUnitを理解したい

JUnitのセットアップ方法はこのリンクにあります。
下の方だったと思います。

注意書き

  • この問題はすべてJUnitを使用して実装します。
  • 各問題は「lvXXTraing()」というメソッドで実装します
  • 別のやり方で「LvXXTraing」というクラスを作り、メインメソッドに実装してもよいです
    public class LvXXTraing {
    public static void main(String[] args) {
        // 問題の回答
    }
    }
  • 各パッケージの関連は以下のように定義します。
  • テストケースの作成も練習します。

jp.zenryoku.practice.train: 練習問題集の問題の回答クラス
jp.zenryoku.practice.train.cls: 練習問題集のテスト対象クラス

問題一覧

基本レベル1の問題

  • LV1:System.out.printlnの応用1
  • LV2:System.out.printlnの応用2
  • LV3:変数の使い方1
  • LV4:変数の使い方2
  • LV5:標準入力を受ける
  • LV6:数字と数字以外の標準出力
    • 「正規表現」に関して
  • LV7:数字の最も下の桁
  • LV8:数値のパーセンテージ
  • LV9:商と剰余を表示
  • LV10:商と剰余を表示2
  • LV11:キャストする
  • LV12:条件分岐1
  • LV13:条件分岐2
  • LV14:条件分岐3
  • LV15:条件演算子(三項演算子)
  • LV16:配列1
  • LV17:配列2 点数の平均を出す
  • LV18:ファイルの読み込み
  • LV19:読み込んだファイルをArrayListに設定
  • LV20:読み込んだファイルをLinkedListに設定
  • LV21:プロパティファイルを読み込む

基本レベル1

LV1:System.out.printlnの応用1

コンソール表示するときには、System.out.println()の引数に値を渡すだけで表示していました。
しかし、他にも表示するときの方法があるので練習がてらに紹介します。

<問題>
System.out.printf()を使用してint型の変数numの値を標準出力に表示してください。
例:
数字の値は3です。

<System.out.printlnで実行するとき>

System.out.println("数字の値は" + num + "です。");

<ヒント>
System.out.printf()というメソッドはSystemクラスにある「out」というフィールド変数のメソッドです。
このことはJavaDocを見ればすぐわかります。
修飾子が「public」かつ「static」なので下のようなコードでアクセスできます。

System.out;

そしてこの「out」のデータ型はPrintStreamクラスです。

今回使用するメソッドのJavaDocに答えが書いてあります。

LV2:System.out.printlnの応用2

<問題>
下のようなプログラムの実行結果を1行のコードで実装してください。
※「セミコロン(;)」をつけたときは必ず改行します。
 つまり下のような書き方で実行してくださいという意味です。

System.out.println( ... );

<実行プログラム>

System.out.println("************");
System.out.println("* Welcome! *");
System.out.println("************");

LV3:変数の使い方1

<問題>
以下のコードを作成してください。

  • int型の変数「num」を宣言してください。
  • String型の変数「moji」を"test"で初期化してください。

最後に上記で作成した変数をすべて下のように一行のコードで表示してください。
※LV2と同じように1行出力してください。

LV4:変数の使い方2

<問題>
クラス「Training1」クラスを作成しTraining1型の変数を宣言してください。
そして、Training1型のクラスオブジェクトを取得して、その名前をコンソールに表示してください。

<ヒント>
Training1クラスは自作してください。
作成するクラスは以下のパッケージにjp.zenryoku.practice.train.cls配置してください。
そして、すべてのクラスはObjectクラスを親に持っています。
つまり、Objectクラスに定義しているメソッドが使用できるということです。
今回使用するメソッドはtoString()です。
同様に、クラスオブジェクトを取得するメソッドもあります。それは上のJavaDocから探してください。

LV5:標準入力を受ける

標準入力は普段パソコンを使用するときにキーボードを使用して文字列を入力すると思いますが、
その「入力」が標準入力になります。

ここで使用する標準入力はScannerクラスを使用します。
java.util.Scannerを使用するのが新しいやり方のようです。

<ヒント>
ちなみに、古いほうの標準入力の受け取りは
Systemクラスにある標準入力(System.in)をそのまま使用します。
下のようなコードです。

// 標準入力の読み取り
int in;
System.out.println("終了するときはbを入力して下さい");
while ((in = System.in.read()) != -1) {
  System.out.write(in);
  if ('b' == in) {
    break;
  }
}

LV6:数字と数字以外の標準出力

<問題>
LV5で作成したような標準入力の受け付けを行い入力した数値を表示してください。
ただし、数字以外が入力された場合は「数字を入力してください」と表示してください。
そして、入力できる桁数は5文字までに制限して、5文字を超える場合は「5文字以内にしてください」と標準出力に表示してください。

<ヒント>
Stringクラスに「matches」というメソッドがあります。

==「正規表現」に関して==
正規表現を使用してアルファベットの「a~zまで」とか数字の「0~9」までとか指定することができます。
数字の場合は「数値」ではないので0が???個のように考えます。
正規表現の例:
[a-z]:「a~z」までの小文字のアルファベット(1文字分)
[0-9]:「0~9」までの数字(1文字分)

[a-z]{2,4}:a~zまでの文字を2回以上、4回以下繰り返すことを示す

<サンプルコード(JUnit使用)>

public class StringTest {
    @Test
    public void test01() {
        String val = "123456";
        if (val.matches("[0-9]{4,}")) {
            System.out.println("Hello!");
        } else {
            fail();
        }
    }
}

<実行結果>

書式文字列に関してはこちらのドキュメントが参考になります。

LV7:数字の最も下の桁

<問題>
整数を入力し、その整数の下1桁目の数字を表示して下さい。
例:表示結果は下のように出力してください。

整数を入力してください
123450
最も下の桁は0です

LV8:数値のパーセンテージ

下の例のように、入力値Aが入力値Bの何%か表示してください。
※出力結果は整数で表示してください。⇒小数点以下は表示しない

<ヒント>
今まで使用していた「int型」は整数を格納する変数です。
パーセンテージは小数点を含むので「int型」は使用できません。
double型を使用します。

例:表示結果

2つの整数を入力してください
12
入力値A:12
24
入力値B:24
Aの値は、Bの50%です

LV9:商と剰余を表示

LV8と同様に2つの整数を読み込み、商と剰余を表示してください。
<ヒント>
商:割り算の結果
剰余:割り算後の余り

例:表示結果

2つの整数を入力してください
11
入力値A:11
5
入力値B:5
AとBの商は2.2です
AとBの剰余は1.0です

LV10:商と剰余を表示2

LV9と同様に出力するのですが、今度は下のように出力してください。
※System.out.printfを使用して、フォーマット文字列には「%f」を使用してください。

例:表示結果

2つの整数を入力してください
4
入力値A:4
3
入力値B:3
AとBの商は1.333333、剰余は1.000000です。

LV11:キャストする

<問題>
下の例のように、入力値Aが入力値Bの何%か表示してください。
ただし、表示するときは以下の2パターンの表示を行ってください。

  1. 出力結果は整数で表示してください。⇒小数点以下は表示しない
  2. 出力結果は小数で表示してください。⇒小数点以下は表示する

<ヒント>
「キャスト」というのはデータ型の変換を意味します。
この問題では「int型~double型へのキャストを使用します」

LV12:条件分岐1

<問題>
標準入力を受け取り、入力した文字列に数字が含まれている場合
標準出力に「Has Number!」を出力
そうでない場合は「No Number!」を出力してください。

例:表示結果

入力してください
uiioi1
入力値:uiioi1
Has Number!

<ヒント>
正規表現が使えます。

LV13:条件分岐2

<問題>
標準入力を受け取り、入力した文字列に「a」が含まれている
もしくは、「z」が含まれている場合に「Hello AZ!」と標準出力に表示する
それ以外は「Hello World!」と表示してください。

<ヒント>
String#contains()が使用できます。
※上の書き方はStringクラスのcontainsメソッドという意味です。

そして、JavaDocにある「CharSequence」はStringクラスに実装(implements)されているので
Stringを渡すこともできます。まとめると以下のクラスを渡すことができます。

  1. CharBuffer
  2. Segment
  3. String
  4. StringBuffer
  5. StringBuilder

LV14:条件分岐3

<問題>
標準入力を受け取り、入力した文字列に「a」が含まれている
かつ、「z」が含まれている場合に「Hello AZ!」と標準出力に表示する
それ以外は「Hello World!」と表示してください。

ヒントはありません。。。

LV15:条件演算子(三項演算子)

<問題>
標準入力を受け取り、入力した文字列に「a」が含まれている場合
標準出力に「Hello A!」と表示
それ以外は「Hello World!」と表示してください。
ただし、作成するコードは4行以内で書いてください。

例:表示結果

入力値:おおお
Hello World!

<ヒント>
条件演算子(三項演算子)の書き方

データ型 変数名 = 条件式 ? TRUEの場合 : FALSEの場合;

LV16:配列1

<問題>
配列長3のint型配列「hako」を宣言して、配列の中に以下の値を設定し
2番目の値を標準出力に表示してください。

<ヒント>

String[] mojimoji = new String[7]; // String型の配列を初期化
mojimoji[0] = "a";
mojimoji[1] = "b";
mojimoji[2] = "c";
mojimoji[3] = "d";
mojimoji[4] = "e";
mojimoji[5] = "f";
mojimoji[6] = "g";
System.out.println("配列の2番目:" + mojimoji[2]);

LV17:配列2 点数の平均を出す

<問題>
A塾には生徒が5人います。この生徒たちのテストの平均を出すために
プログラムをループ文を使用して作ってください。

仕様は以下の通りです。

  1. 生徒はA君、B君、C君、D君、E君の5人
  2. 点数は標準入力から入力
  3. 「平均点はXXXです」と標準出力に表示

例:表示結果

A君: 10点
B君: 20点
C君: 30点
D君: 40点
E君: 50点
平均点数は:30点

LV18:ファイルの読み込み

<問題>
「Wepons.csv」ファイルから文字列を読み込み中身を標準出力に表示してください。
※読み込むファイルは/src/main/java/resources以下に配置してください。

<ヒント>

LV19:読み込んだファイルをArrayListに設定

<問題>
LV18で読み込んだファイルのデータをjava.util.ArrayListにセット、データの3行目を標準出力に表示してください。

例:表示結果

CSVののデータ数は20
カテゴリID: 3
名前: たけやり
カテゴリLV: 1
値段: 10
攻撃力: 3
効果: -
両手FLG: TRUE
射程: 1
リロード: -
説明: たけでできた、やり

LV20:読み込んだファイルをLinkedListに設定

<問題>
LV18で読み込んだファイルのデータをjava.util.LinkedListにセット、データの3行目を標準出力に表示してください。

例:表示結果

CSVののデータ数は20
カテゴリID: 3
名前: たけやり
カテゴリLV: 1
値段: 10
攻撃力: 3
効果: -
両手FLG: TRUE
射程: 1
リロード: -
説明: たけでできた、やり

LV21:プロパティファイルを読み込む

LV18と同じ、/src/main/java/resources以下に「test.properties」を配置してこのファイルの中身を標準出力に表示してください。

例:表示結果

KEY: macVALUE: "マッキントッシュ"
KEY: winVALUE: "ウィンドウズ"
KEY: adsVALUE: "グーグルアドセンス"

<ヒント>
java.util.Properties#load())を使用してください。

LV22:メソッドの処理結果を確認する1

前提として、問題のメソッドは「lv22Traing()」に書きます。

それ以外に、「test01()」 メソッドを作成してください。引数なし、返り値はint型です。

test01()の処理内容は、自分で考えてみてください。

<問題>
test01の処理結果が「10」になることを確認するテストケースを作成して、テスト結果がOKになるようにしてください。

LV23:メソッドの処理結果を確認する2

前提として、問題のメソッドは「lv23Traing()」に書きます。

それ以外に、「test02()」 メソッドを作成してください。引数なし、返り値はString型です。

<問題>
test02の処理結果が「"aaa"」になることを確認するテストケースを作成して、テスト結果がOKになるようにしてください。

LV24:メソッドの処理結果を確認する3

前提として、問題のメソッドは「lv24Traing()」に書きます。

それ以外に、「test03()」 メソッドを作成してください。引数int型、返り値はString型です。

<問題>
test01の処理結果が「"a1b"」になることを確認するテストケースを作成して、テスト結果がOKになるようにしてください。

関連ページ一覧

Eclipse セットアップ(Mac版)

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseCDTをインストール〜
  3. Setup OpenGL with JavaJOGLを使う準備 for Eclipse
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)
  6. Eclipse SceneBuilderを追加する
  7. JavaFX SceneBuilder EclipseSceneBuilder連携~

Java Basic一覧

  1. Java Basic Level 1 〜Hello Java〜
  2. Java Basic Level2 〜Arithmetic Calculate〜
  3. Java Basic Level3 〜About String class〜
  4. Java Basic Level 4〜Boolean〜
  5. Java Basic Level 5〜If Statement〜
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 〜Traning of If statement〜
  8. Java Basic Level8 〜How to use for statement〜
  9. Java Basic Level 8.5 〜Array〜
  10. Java Basic Level 9〜Training of for statement〜
  11. Java Basic Level 10 〜While statement 〜
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2〜
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1〜
  17. Java Basic JUnit 〜テストスイートの作り方〜

Git関連

  1. Java Git clone in Eclipse 〜サンプルの取得〜
  2. Eclipse Gitリポジトリの取得 GitからソースをPullしよう〜
  3. IntelliJ IDEA GitGitリポジトリからクローン〜

JavaFX関連ページ

  1. Eclipse SceneBuilderを追加する
  2. JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
  3. JavaFX SceneBuilder〜ボタンにメソッドを割り当てるワンポイント〜
  4. Java プロコンゲーム 〜見た目の作成(SceneBuilderの使用)〜

ステップアップ関連ページ一覧

  1. Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
  2. ステップアッププログラミング〜Java FxでHelloWorld解説〜
  3. Java StepUpPrograming〜JavaFX で四則計算〜
  4. Java StepUpPrograming〜JavaFXで画面切り替えを作る1〜
  5. Java StepUpPrograming〜JavaFXで画面切り替え2ボタン作成〜
  6. Java StepUpPrograming〜JavaFXで画面切り替え3アクション〜
  7. Java StepUpPrograming〜JavaFXで画面切り替え4Pane切り替え〜
  8. Java StepUpPrograming〜JavaFXで画面切り替え5WebEngine

JavaFX + ND4Jで機械学習準備

  1. JavaFX + ND4J〜数学への挑戦1:ND4Jのインストール〜
  2. JavaFX + ND4J〜数学への挑戦2: 行列の計算〜
  3. Java + ND4J 〜数学への挑戦3: ベクトル(配列)の作成方法〜

オブジェクト指向関連ページ

  1. オブジェクト指向の概念1〜OracleDocのチュートリアル1〜
  2. オブジェクト指向の概念2〜クラスとは〜

Java Basic Class 〜メインメソッドを変更しないで処理を変える〜

メインメソッドを変更しない

表題にある子の文言の意味は、下のように実行する処理をクラスに任せてしまうという方法です。
その他にも、アイディアの数だけあるのでよりよい方法を考えるのも面白いと思います。

  1. 処理の内容を分割してやる
  2. 処理を引数、入力値でハンドルする

数え上げればきりがありませんが、今回の「処理をクラスに任せてしまう」という方法は極端ですが、下のような方法です。

public static void main(String[] args) {
    SomeClassA clsA = new SomeClassA();
    clsA.execute();
}

これで、メインメソッドを修正する必要がありません。

クラスを使用すると

メインメソッドを変更しなくても処理を変更できます。

具体的に、下のようにやります。
以前作成したメインメソッド

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String input = scan.next();

        FirstCls first = new FirstCls();
        boolean isNumber = first.isNumberString(input);
        if (isNumber) {
            System.out.println(input + "は数字です。");
        } else {
            System.out.println(input + "は数字ではありません。");
        }
    }
}

このクラスから呼び出しているFirstClsを修正してやれば、Mainクラスは修正する必要がありません。

なんか「とんち」のような話ですが(笑)

応用レベル1

現段階では、応用幅が小さいのでMainメソッドを修正します。

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String input = scan.next();

        FirstCls first = new FirstCls();
        if ("exe".equals(input)) {
            first.execute();
        }
        boolean isNumber = first.isNumberString(input);
        if (isNumber) {
            System.out.println(input + "は数字です。");
        } else {
            System.out.println(input + "は数字ではありません。");
        }
    }
}

FirstClsのexecuteメソッドを起動するように修正しました。

クラスに処理を追加する

はじめの入力で「exe」と入力するとFirdtClsのexecuteメソッドが起動します。

単純に、FirstClsの中に、適当な処理を実装しただけです。

public void execute(Scanner scan) {
    System.out.println("*** EXECUTEを起動します ***");
    Map<String, String> map = new HashMaplt;>();
    map.put("test", "Testing this program!");
    map.put("prac", "Practice this program!");
    map.put("try", "Try this program!");
    while(true) {
        System.out.print("コマンドを入力してください: ");
        String str = scan.next();
        if (map.containsKey(str) == false) {
            break;
        }
        System.out.println(map.get(str));
    }
}

今回は、Mapインターフェースを使用して見ました。
キーと値がセットになって、データの取り出し、保存を行うことができます。
ここで言う保存はJavaが起動している間だけの保存です。

このままでは、大した発展があったようには思えませんので、一捻り加えます。ちなみに、execute()の処理が終わった後に、何かしらの文言が出ます。

一捻り

単純ですが、FirstClsにあるメソッドisNumberString()を呼び出すように修正します。

public void execute(Scanner scan) {
    System.out.println("*** EXECUTEを起動します ***");
    Map<String, String> map = new HashMap<>();
    map.put("test", "Testing this program!");
    map.put("prac", "Practice this program!");
    map.put("try", "Try this program!");
    while(true) {
        System.out.print("コマンドを入力してください: ");
        String str = scan.next();
        if (map.containsKey(str) == false) {
            break;
        }
        isNumberString(str);
        System.out.println(map.get(str));
    }
}

こんな感じです。
今日のところは、ここまでにしておきます。

でわでわ。。。

関連ページ



Java Basic Arrays 〜多次元配列〜

イントロダクション

個人的にOpenCVの学習を行なっているところで、配列に関して触れていなかった事に気が付いたのでここで触れておこうと思います。

ちなみに、OpenCVで画像(imgデータ)を扱うのですが、これは平面画像だと2次元配列(縦、横の配列なので2次元配列)、そして、透過するデータを追加すると3次元。。。と配列のデータ量が増えていきます。

配列の解説

While文で配列をループするコードを解説していますが、配列に関しても解説しています。

多次元配列

論より証拠、ソースを見てみると一目瞭然ですが、配列のイメージは持っておくようにしましょう。上の動画を見てもらえれば簡単なイメージが作れると思います。

サンプルコード

下のリンクはGithubへのリンクになります。コードの全体があり、コピペもしやすいと思われます。
そして、プログラムの内容に関しては次の通りです。

  1. String型の1次元配列「lv1Array」を宣言します。
  2. 同様に2次元配列「lv2Array」を宣言します。
  3. 3次元配列「lv3Array」を宣言。
  4. 1次元配列をFOR文で表示します。
  5. 2次元配列を2次元ループで表示します。※2次元ループはFOR文が2階層あります。
  6. 3次元配列を3次元ループで表示します。※3次元ループはFOR文が3階層あります。

Sample_Array.java

public class Sample_Array {
  /** メインメソッド */
    public static void main(String[] args) {
        // 1次元配列
        String[] lv1Array = new String[] {"a", "b", "c"};
        // 2次元配列
        String[][] lv2Array = new String[][] {{"a", "b", "c"}, {"d", "e", "f"}};
        // 3次元配列
        String[][][] lv3Array = new String[][][] {
            {{"a", "b", "c"}, {"d", "e", "f"}}
            ,{{"g", "h", "i"}, {"j", "k", "l"}}
            ,{{"m", "n", "o"}, {"p", "q", "r"}}
            };
        // 1次元配列を表示する
        System.out.println("*** 1次元配列を表示 ***");
        for (String nakami : lv1Array) {
            printf("", nakami);
        }
        // 2次元配列
        System.out.println("\n*** 2次元配列を表示 ***");
        for (String[] nakamiLv2 : lv2Array) {
            for (String nakami : nakamiLv2) {
                printf("", nakami);
            }
        }
        // 3次元配列
        System.out.println("\n*** 3次元配列を表示 ***");
        for (String[][] nakamiLv3 :lv3Array) {
            for (String[] nakamiLv2 : nakamiLv3) {
                for (String nakami : nakamiLv2) {
                    printf("", nakami);
                }
            }
        }
    }
        /** コンソール出力メソッド */
    private static void printf(String label, String value) {
        System.out.print(label + "" + value);
    }
}

実行結果が下になります。

<理解の仕方>

=>理解の仕方は人それぞれなので自分の中でイメージを作ってください。

ちなみに、配列にはint型の配列、文字列型の配列。。。などいろいろありますが、「XXX型の変数」があれば、「XXX型の配列」があります。

筆者の場合

筆者の場合は、以下のようなイメージを持っています。

変数

小さな段ボール箱のイメージで持っています。そこに数値型、文字、文字列型、クラス型の値を入れる(セット)するイメージです。

配列

配列になると上記の段ボールより大きい段ボールをイメージします。

次元数が増えると段ボールもより大きくなります。

1次元配列

1次元配列は変数が、おおきな箱の中に並ぶようなイメージを持っています。

String[] hako = new String[] {"1XX", "2XX", "3XX" ...};
hako[0] => "1XX"
hako[1] => "2XX"
hako[2] => "3XX"

2次元配列は変数が、さらに大きな箱の中に並ぶようなイメージを持っています。

String[][] hako = new String[][]{{{"11X", "12X", "13X"},{"21X", "22X", "23X"},{"31X", "32X", "33X"} ...};
hako[0][0] => "11X"
hako[0][1] => "12X"
hako[0][2] => "13X"
hako[1][0] => "22X"
hako[1][1] => "22X"
hako[1][2] => "22X"

こんな感じです、実際には目に見えるものではないので「イメージ」になってしまいます。プログラムを実行すれば「結果」をみることができるのでより具体的なイメージができると思います。

関連ページ一覧

OpenCVで画像解析の基本を学ぶ

  1. Java OpenCV Lv4 〜画像の中身をみてみる〜「画像データは配列になっている」

<Java Step1〜ミニゲーム作成>

Java Basic JUnit 〜テストの作り方〜

イントロダクション

今までに触れたことのない技術(OpenCvなど)を使おうと思ったら色々と動かしてみたいのが人情、そんな時に使えるフレームワークの使い方を記載します。
その名はJUnitです。
具体的には、参考資料、参考サイトなどを見ながらプログラムを作成する、作成したプログラムの。。。

  1. メソッドのみを動かす。
  2. 全体を動かす。
  3. 一部切り出して動かす。

上記のことが、本体プログラムに影響せず実行できるところが良いところです。

JUnit

JUnitは、「テスト用のフレームワーク」として有名なものです。「テスティングフレームワーク」という言い方が多いと思います。

英語で「Testing framework」といえばなんとなくわかるけど、日本語だとなんか別な意味があるのでは?と疑ってしまうのは筆者だけでしょうか?
とりあえず、『いろんな言い方をして混乱するのは良くない』といいたいだけです。失礼。。。

この記事のタイトルにある「テストスイート」という言葉も「テストケース」を意味するものです。JUnitでの「@Test」のついたメソッドのことです。
色々な言い方があり混乱してしまいがちですが「何を指しているのか?」に注意すればあまり混乱しないと思います。

JUnitの概要

JUnit(本家サイトへのリンクです)は、ズバリ「アノテーション『\@』」でテストの準備、テスト、テストの後始末をっコントロールできる便利なフレームワークです。いろんな書籍でいろいろ書いていると思いますが、基本は「\@Test」「/@Before」「\@After」のアノテーションをつければ動きます。もっと言うと「\@Test」アノテーションのみでよいです。※今回実装したJUNIT5ではBeforEach, AfterEachのように名前が変わっています。

JUnitの設定方法

IntelliJ IDEAでの設定方法です。

Mavenを使用して、pom.xmlに以下のような記述を追加、再ビルド(Mavenビルド)を行う。"dependencies"タグの中に追加する
タグの階層があるので、ちょっと混乱しがちですが、projectタグの直下に記述します。

<dependencies>
  <!-- この部分がJUNITの記述 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

追伸、ほかのOpenCVとかLWJGLなどもこのdependenciesタグの中に追記します。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd
                                http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>jp.zenryokuservice</groupId>
    <artifactId>TextRPG</artifactId>
    <version>0.8-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.objecthunter</groupId>
            <artifactId>exp4j</artifactId>
            <version>0.4.8</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

コードの実行

ズバリ、「@Test」をメソッドの頭につけるだけです。

import jp.zenryoku.practice.sample.SampleLv1Hello;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.Assert.assertEquals;

/**
 * サンプルテストクラス
 */
public class SampleTest {
    /** テスト対象クラス */
    private SampleLv1Hello target;

    /** テストの準備 */
    @BeforeEach
    public void init() {
        target = new SampleLv1Hello();
    }

    @Test
    public void test01() {
        System.out.println("Hello JUnit");
        target.testMethod();
    }

    @Test
    public void test02() {
        target.testMethod(1, 2);
        target.testMethod(4, 9);
        target.testMethod(5,8);
        target.testMethod(6, 7);
    }

    @Test
    public void test03() {
        // 返却値が正しいか確認する
        assertEquals(2, target.testMethod(1, 1, true));
        assertEquals(2, target.testMethod(5, 3, false));
        assertEquals(3, target.testMethod(1, 1, true));
    }
}

Javaで開発をしていたらすぐに目にすると思うのですが、改めて使い方をみてみようと思います。
<作業動画>

手順(Eclipse)

  1. EclipseにJUnit4(JARファイル)をビルドパスにつなぐ
  2. テストクラスを作る
  3. 実行する
  4. あとは色々といじって遊ぶ

サンプルコード(JUnit4 ※古い)

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.junit.runners.JUnit4;
import org.opencv.core.Mat;

import zenryokuservice.gui.lwjgl.kakeibo.opnecv.ReceiptCv;

/** JUnit4を使う宣言 */
@RunWith(JUnit4.class) 
public class ReceiptCvTest {
    /** テスト対象のクラスをフィールドで保持する */
    private ReceiptCv test;
    /**
     * Bforeアノテーションで各テストを実行する前に
     * 実行するメソッド
     * テストのためのデータセットを用意したり、クラスの呼び出しを行なったりする
     */
    @Before
    public void setup() {
        test  = new ReceiptCv();
    }
    @After
    public void terminated() {
        // テストの終了処理(メモリ開放)
        test = null;
    }
    /** テストケース1 */
    @Test
    public void test1() {
        test.helloCv();
    }
    /** テストケース2 */
    @Test
    public void test2() {
        // イメージファイルを読んでみる
        Mat matrix = test.loadImg("download-1.jpg");
        System.out.println(matrix.dump());
    }
}

テストケースの考え方

じゃんけんゲームを作成しているときに、入力チェックのメソッドを作成したとき。

このメソッドをテストするための「テストケース」を作成するときのことを解説しています。

関連ページ一覧

Java Basic

  1. Java Basic Level 1 〜Hello Java〜
  2. Java Basic Level2 〜Arithmetic Calculate〜
  3. Java Basic Level3 〜About String class〜
  4. Java Basic Level 4〜Boolean〜
  5. Java Basic Level 5〜If Statement〜
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 〜Traning of If statement〜
  8. Java Basic Level8 〜How to use for statement〜
  9. Java Basic Level 8.5 〜Array〜
  10. Java Basic Level 9〜Training of for statement〜
  11. Java Basic Level 10 〜While statement 〜
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2〜
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1〜
  17. Java Basic JUnit 〜テストスイートの作り方〜