文字列処理

Revised: Dec./8th/2002

文字は基本データ型の char 型で Unicode 文字としてあらわしますが、文字列は java.lang.String クラスのオブジェクトとして取り扱います。String の名を冠したクラスには java.lang.StringBuffer というものもあります。 API に関しては紹介済みですし、詳細は API 仕様書を参照していただければよいでしょう。

String 型オブジェクトは固定長の文字列、 StringBuffer は可変長の文字列ということになっていますが、それぞれの選択によるパフォーマンスについて考えて見ましょう。

String オブジェクトのメモリ確保

String クラスのメモリ確保の仕組みは特殊です。文字列のリテラルが指定されると、 JVM は文字列用のプールにオブジェクトを作成し、同じ文字列が指定されると、当該プール内へのポインタをつけることで対応します。

String str1 = "Hello!";
String str2 = "Hello!";

上のサンプルでは、二つの String 型変数 str1, str2 が宣言されており、 "Hello" という文字列のリテラルが代入されています。一回目の "Hello!" により、文字列プールにオブジェクトが作成され、二回目の "Hello!" ではそのオブジェクトへのポインタによって代用されます。従って、 str1 == str2 は true を返します。

String str3 = new String("Hello!");

一方、String クラスのコンストラクタを使って new すると、プール内にある文字列でも、別途オブジェクトが作成されることになるので、作成に費やすコストもメモリ効率も悪化します。できるけどやらない方が良いという例になります。

文字列の連結

+ 演算子は、一方が文字列の場合、他方を String 型に変換して連結します。

String str = "Hello";
str += ", ";
str += "world!";

上の例では、最初に "Hello" という文字列を str に代入して、続いて、 ", " と "world!" を連結しています。結果として、str には "Hello, world!" という文字列が代入されることになります。

この例では、 "Hello"、", "、"world!"、 "Hello, "、"Hello, world!" という五つのオブジェクトが作成されています。これは効率が悪い方法です。

文字列を連結するならば、一つのステートメント内で行うべきです。

String str = "Hello" + ", " + "world!";

これは、コンパイル時には StringBuffer を使って append() し、最後に String 型に変換してくれます。

StringBuffer sbuf = new StringBuffer("Hello");
sbuf.append(", ").append("world!");
String str = sbuf.toString();

StringBuffer を使う場合、最初に作成されたオブジェクトのメモリ領域内で行われるので、一時的な文字列を新規にオブジェクトとして作成するコストが無くなり、不要なメモリ領域の消費も抑えられます。

文字列の分割

文字列を特定の区切り子(delimiter) で分割したいことがよくあります。例えば、 CSV (comma separated value) データのフィールド分割や、改行文字の別の文字への置換などが代表例です。

このような場合、 java.util.StringTokenizer が便利です。次の例は CSV を HTML のテーブルに変換するものです。

import java.util.*;
class StringTokenizerDemo {
	public static void main(String[] args) {
		String str = "E29910,msugai,sugai manabu,";
		StringTokenizer strToken = new StringTokenizer(str, ",");
		System.out.print("<table border=\"1\"><tr>");
		while(strToken.hasMoreTokens()) { 
			System.out.print("<td>");
			System.out.print(strToken.nextToken().toString());
			System.out.print("</td>");
		}
		System.out.println("</tr></table>");
	}
}
C:\java>javac StringTokenizerDemo.java
C:\java>java StringTokenizerDemo
<table border="1"><tr><td>E29910</td><td>msugai</td><td>sugai manabu</td><td>sug
ai@fides.dti.ne.jp</td></tr></table>
C:\java>


Copyright © 2002 SUGAI, Manabu. All Rights Reserved.
SEO [PR] !uO z[y[WJ Cu