文字列の処理はいろいろなところで出てきます。Chapter4で紹介した基本型には文字列を扱うものはありませんでしたが、文字列を扱う型は用意されています。そのうちのString型がいちばんよく使われます。またString型とあわせて、文字列自体を比較的自由に編集できるStringBuffer型についても説明しましょう。これらは、実際には「オブジェクト」と呼ばれるものであり、型というよりも「クラス」というほうが適切ではあります。オブジェクトは8章以降に説明をしますので、ここでは、ともかくそういう型があるということだけを知っておいていただければよいでしょう。
まず、この章で入力するプログラムとアプリケーションのひな形を作っておきましょう。手順については、これまでの章とまったく同じですので、ここでは手順は示しません。ウィザードの画面のうち、ポイントになる部分だけを示しておきます。クラスの名前を設定する時、パッケージの名前と「public static void main(String[] args)」のチェックを入れておく事を忘れないようにしましょう。
JavaString.javaのpublic void mainのブロックの最後の部分に、以下のようなプログラムを追加してください。追加して、「実行」ボタンをクリックします。コンソールには2行分出力されているはずです。
String s = "今日のサンプルはシンプル";
String t;
t = s + "だけどややこしい";
System.out.println(s);
System.out.println(t);
まず、文字列の定数、つまり一定の文字列をプログラムの中で表現するのには、追加したプログラムの最初の行にあるように、半角のダブルクォーテーション " " で囲みます。長さはほとんど無制限と思ってよいようなのですが、ソースファイルに入力するという意味では適当な限度はあるかと思います。
そして、文字列変数は、String型変数として、intなどと同じように定義すればかまいません。この場合には、変数sとtに文字列を記録することができると考えておいていいでしょう。文字列を代入するには、プログラムにあるように=を使いますが、これも数値と同じです。
途中に、「t = s + "だけどややこしい";」という記述があります。演算子+は、数値では加算でしたが、演算子の左右が文字列であれば、文字の結合になります。それまでにsには「今日のサンプルはシンプル」という文字列が代入されています。それに「だけどややこしい」という文字列を結合した結果を、変数tに代入しています。したがって、処理後には変数tの値は「今日のサンプルはシンプルだけどややこしい」となっており、メッセージペインにそのように出力されます。なお、文字列で使える演算子はこの+だけで、-や*などは使えません。
文字列はダブルクォーテーションで囲みますが、ダブルクォーテーション自体を文字列に入れたいときには、「\"」と記述します。つまり、"これが\"Java\"ってもんだ"という記述は「これが"Java"ってもんだ」という文字列になるという具合です。このように、特別な記号を記述するための\で始まる記述を「エスケープシーケンス」と呼びます。他には、文字列中に\を記述するには\\と記述しないといけません。改行は、\r\nで記述します。タブは、\t で記述します。なお、この\記号はフォントによっては\(バックスラッシュ)となりますので、その場合は適宜読み替えてください。
文字列の長さを知りたいことはよくありますが、そのためには、文字列、典型的にはString型の文字列変数に対して、「.length()」という記述を加えることです。こうした何かの機能を呼び出す仕組みを「メソッド」と呼んでいます。変数にピリオドを続け、さらに機能名を続けて記述します。メソッドは自分で定義することもできますが、このlengthメソッドは、Javaの実行環境で最初から用意されているのです。つまり、文字列変数にlengthメソッドを適用すると、文字列の長さが返される、つまり結果として文字列の長さが得られるということになります。
また、文字列の一部分を取り出すsubstringというメソッドもあります。それらの利用例は以下のとおりです。さきほど入力したプログラムの最後の部分に追加して、実行してみてください。
int strLen = t.length();
System.out.println( t + "の長さは" + strLen + "文字です。" );
System.out.println( t.substring( 5,8 ) );
すでに説明したように、lengthやsubstringというメソッドがString型に対して利用できるように、あらかじめJavaの実行システムで定義されています。メソッド名に続いて、()で閉じて値を指定しますが、この値を「引数」と呼びます。この引数とは、たとえば、substringというメソッドに与える必要な情報と考えてください。lengthには引数はありませんが、引数がない場合も()は必要です。
substringは、左側のピリオドの前に適用した文字列変数に対し、その文字列の一部分を取り出します。何文字目から何文字目を取り出すかということを引数で指定します。引数には2つの数値5と8を指定しますが、それらはカンマで区切ります。この引数の数値は、文字というよりも、文字と文字の間に付けられた番号と言えばよいでしょう。つまり、
文字列: | 今 | 日 | の | サ | ン | プ | ル | は | シ | ン | プ | ル | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
番号: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
という具合に番号が割り振られているので、引数に指定した5から8ということで、番号5の部分から番号8の部分までを取り出して、「プルは」という文字列が得られており、それがメッセージペインに出力されるわけです。つまり、「5文字目から8文字目」ということではありません。結果的には、「6文字目から8文字目」ということになります。
追加したプログラムのうち2行目のprintlnの引数では、文字列と数値を+演算子で加算しています。このような場合、int型のstrLenは、代入されている数値を示す数字の文字列に置き換えられ、文字列の結合処理が行われます。つまり、strLenは20という値ですが、式の中では"20"という文字列になるという具合です。文字列の結合中では、数値データも気軽に含めてかまわないということになるでしょう。
String型については、ほかにもいろいろなメソッドがあって、さまざまな文字処理ができますが、以後のサンプルプログラムで出てきたときに、どのような機能なのかを説明することにしましょう。
少しプログラミングの知識がある人は、文字列がどうやって記録されているのか気になるかもしれませんが、はっきり言って、ほとんどの場合、具体的な記録方法を知らなくてもプログラムは作成できます。ともかく、String型という自由に文字列を記録できる領域が、変数定義するだけで用意されると思っていてけっこうです。「文字列を覚える」という抽象的な理解でプログラムは作成できるということです。ちなみに、文字コードはUNICODEですので、1バイトコード、2バイトコードという区別もありません。「A」(半角)も「A」(全角)も同じ1文字としてカウントされます。
文字列はString型だけではありません。もう1つStringBufferというのを知っておくと、複雑な文字列処理をするときにはかなり便利です。Stringだとつなげたり、部分的に文字列を取ってくることができる点は、すでに説明したとおりです。同じことがStringBufferでも可能ですが、さらに、記録している文字列の途中に文字を割り込ませたり、末尾に文字列をくっつけるということが行えます。
JavaString.javaのinitのブロックの最後の部分に次のようなプログラムを追加して、保存、コンパイル、実行としてみてください。
StringBuffer sb = new StringBuffer( "これは文字列です。" );
System.out.println( sb );
sb.insert( 3, "部分修正可能な" );
System.out.println( sb );
sb.append( "便利ですね。" );
System.out.println( sb );
StringBuffer型の変数を用意したとき、プログラムの1行目にあるように、new StringBuffer()という記述が必要です。このあたりはStringとは違うところですが、基本型とString以外は、このように「new クラス名(引数)」によって、実際にデータを保持したりする記憶領域が割り当てられます。このように表現すると難しそうですが、要はこう書けば、StringBufferが使えるようになると考えてもらってかまいません。引数に文字列を指定すると、その文字列が含まれたStringBufferが得られます。
そして、StringBuffer型の変数に対して、insertメソッドを適用することができます。このメソッドは2つの引数を取り、1つ目が何文字目(substringの文字位置カウントと同じ規則)から挿入するかを指定し、2つ目に実際に挿入する文字列を指定します。
appendは、1つの文字列を引数に指定して、StringBufferの末尾に文字を追加します。こうしたメソッドがあるので、StringBufferの文字数は変化します。文字列数は、length()メソッドで求めることができます。また、substringメソッドもString型と同様に利用できます(この説明はちょっと端折っていますが、結果的にそうなることを知っておけば問題ありません)。
プログラムには6行分を追加しましたが、各行ごとに変数sbの文字列がどう変化するかをじっくりと追っていただければ、各メソッドの機能の理解を助けるのではないでしょうか。
5-1:String型の変数a、b、cを定義し、それらに文字列「チューハイ」「梅」「レモン」を代入する。そして、これらの変数とString型用のメソッドだけを使って、メッセージペインに「梅チューハイ」「レモンチューハイ」「レモンハイ」と表示すること。
5-2:String型の変数aに、「情報処理技術」という文字列を代入する。そして、適当に変数をいくつ作ってもいいので、1文字目、2文字目、…と1文字ずつ違う変数に代入すること。変数名などは自由につけてかまわない。それらの変数を、すべてメッセージペインに出力し、1文字ずつばらばらになったことを確認すること。
5-3:StringBuffuer型の変数sbに、「プログラミングはむずかしい」という文字列を入力すること。String型変数sに「もっと」という文字列を入力すること。そして、これらの変数とメソッドだけを使って、メッセージペインに「プログラミングはもっともっとむずかしい」と表示すること。