Java 文字列管理 例

文字列から部分文字列を探し、その位置を基準として部分的な文字列を取得

代入式の形態で入力した文字列から、=の左辺と右辺に分けて表示するプログラムを作成します。
式の文字列から左辺の文字列を取得するstaticメソッドをgetNameの名前、 右辺の文字列を取得するstaticメソッドをgetValueの名前で、それらメソッドを持つAssignmentのクラスを作成します。
以下に実行例を示します。(が入力です)

Z:\Java>java Assignment
代入式>abc=123
abcの名前に、123が設定
Z:\Java>java Assignment
代入式>xy=5+4
xyの名前に、5+4が設定
Z:\Java>java Assignment
代入式>abcdefg
nullの名前に、nullが設定
Z:\Java>java Assignment
代入式>xy=
xyの名前に、が設定

【考え方】 "="の文字列をindexOfメソッドで探して、先頭から見つかった位置までの部分文字列を、 substringメソッドで取得します。

import java.util.*;
public class Assignment {
	public static String separator = "=";

	public static String getName(String str){
		int idx = str.indexOf(separator);// strの文字列からseparatorの位置を探す
		if( idx == -1 ) return null;
		String name = str.substring(0, idx);// strの文字列で、0からidxの部分文字列を取得
		return name.trim();//name文字列前後の空白文字を除いた文字列を返す
	}
	public static String getValue(String str)
	{
		int idx = str.indexOf(separator);
		if (idx == -1) return null;
		String val = str.substring(idx + 1);// strの文字列のidx+1番目以降部分文字列を取得
		return val.trim();
	}
	public static void main(String[] arg)
	{
		Scanner stdin = new Scanner(System.in);
		System.out.print("代入式>");
		String s1 = stdin.nextLine();
		String n1 = Assignment.getName(s1);
		String v1 = Assignment.getValue(s1);
		System.out.println(n1 + "の名前に、" + v1 + "が設定");
	}
}

上記のように作ったクラスは、別の作品で再利用できます。

次の実行結果のように、入力した文字列において、=の文字列の左右が、同じ文字並びかどうかを評価する 実験的なプログラムです。(が入力です)

Z:\Java>java Test
代入式>xxx = zzz
xxxとzzzは一致しません
Z:\Java>java JTest02
代入式>xxx = xxx
xxxとxxxで一致しました

【考え方】 前述で作成したAssignmentクラスのメソッドを利用すれば、簡単です。 切り出した左右の文字列比較は、equalsメソッドを使わないといけない点に注意ください。

import java.util.*;
public class JTest02{
	public static void main(String[] arg){
		Scanner stdin = new Scanner(System.in);
		System.out.print("代入式>");
		String s = stdin.nextLine();
		String a = Assignment.getName(s);
		String b = Assignment.getValue(s);
		if (a.equals(b) == false){// a と bの文字列が正しくないかの判定
			System.out.println(a + "と" + b + "は一致しません");
		}else{
			System.out.println(a + "と" + b + "で一致しました");
		}
	}
}
 

文字列は、PrintWriterクラスで、簡単にファイル化できます。

(PrintWriteに似ているクラスで、「PrintStream」があります。
System.outのクラスは、「PrintStream」になっており、printメソッドで自動的にフラッシュする仕様になっています。

new PrintWriter("test.html")の実行で、 "test.html" のファイルを作れます。
これで得られるのは、ファイルに書きこみストリームを管理するオブジェクトで、 後はclose()メソッドを実行するまでに、printlnメソッドなどによる書き込んだ順番のファイルが作られます。

 なお、 このようなファイル操作などを使う場合は、メソッド定義で、throws Exception などの記述が必要となります。
既存のメソッドの中には、この記述が、なくてはならないものがあるのです。

import java.io.PrintWriter;

public class Test {
	public static void makeFile() throws Exception  {
		PrintWriter pw = new PrintWriter("test.html");//ファイル作成
		pw.println("<html>");//ファイルへの書き込み
		pw.println("<body>");
		pw.println("TEST");
		pw.println("</body>");
		pw.println("</html>");
		pw.close();// ファイル処理を閉じる
	}
	public static void main(String[] argv) throws Exception  {
		makeFile();
	}
}

作成される"test.html"の内容を以下に示します。

<html>
<body>
TEST
</body>
</html>

なお、makeFile直後のthrows Exception を記述しない場合は、コンパイル時で次のエラーが指摘されます。

Z:\Java>javac Test.java
Test.java:5: 例外 java.io.FileNotFoundException は報告されません。
スローするにはキャッチまたは、スロー宣言をしなければなりません。
   PrintWriter pw = new PrintWriter("test.html");//ファイル作成
                     ^

この意味は、「ファイルのオープンエラーに対する処理」を書かなければならない(スローしなければならない)意味のメッセージです。
その方法として、キャッチまたは、スロー宣言が必要という意味です。
そこで、上記プログラムでは、、スロー宣言(throws Exception )をしています。これはエラー例外を外部に任せる処理です。
例外エラーがあればこの情報をメソッドの呼び出し側へthrows(投げる)指示です。
そこでもエラー処理をしない場合は、 またメソッドの呼び出し側へthrows(投げる)する必要があります。
この場合であれば、PrintWriterに投げる指示があり、それをmakeFileメソッド内部で処理しないで呼び出し側へ投げています。
よって、mainで処理をしなければなりませんが、そこでもせずにまたthrows(投げる)ています。
この場合は、mainの呼び出し元にであるJVMがエラー検出することになり、ここで検出すると実行エラーで停止します。