<本章の目的> String 型を理解する。そろそろJava言語らしくなってきたぞー(笑)!
●問題7-3-1 入力された大文字を小文字に変換するプログラムを作って下さい。
○答え
import java.io.*;
public class CopyLower{
public static void main(String[] args){
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
try{
String line;
while((line=reader.readLine())!=null){
line=line.toLowerCase();
System.out.println(line);
}
}catch(IOException e){
System.out.println(e);
}
}
}
○実行結果
D:\atsushi\Java\List7-5>java CopyLower
This is Japan.
this is japan.
12345
12345
日本語
日本語
This is Japan.
this is japan.
^Z
-- Press any key to exit (Input "c" to continue) --
○解説
Java言語の文字列である String クラスオブジェクトは、書き換えることの出来ない文字列です。
String クラスのどんなメソッドを使っても、文字列の内容を書き換えることは出来ません。
ただし、String クラス変数は自由に書き換えることが出来ます。
内容を書き換えるクラスとしては、java.lang.StringBuffer というクラスがクラスライブラリに用意されています。
詳しくは問題7-3-2の解説を参照して下さい。
toLowerCase メソッドは、文字列中の大文字をすべて小文字に変換した、新しい文字列を返します。
したがって、line.toLowerCase() が実行された後においても line の内容は変わりません。
しかし、直後に自身への代入が実行され、line の内容は変わります。
すべての謎は問題7-3-2で明らかに(笑)!
実行結果より、2 バイト文字にも対応していることが分かります。
○補足
toUpperCase メソッドは、文字列中の小文字をすべて大文字に変換した、新しい文字列を返します。
●問題7-3-2 入力文字列中の「。」を「.」に、「、」を「,」に変換して出力するプログラムを作って下さい。
○答え
import java.io.*;
public class Convert1{
public static void main(String[] args){
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
try{
String line;
while((line=reader.readLine())!=null){
line=line.replace('。','.');
line=line.replace('、',',');
System.out.println(line);
}
}catch(IOException e){
System.out.println(e);
}
}
}
○実行結果
D:\atsushi\Java\List7-6>java Convert1
abc
abc
12345
12345
はじめまして、こんにちは。
はじめまして,こんにちは.
^Z
-- Press any key to exit (Input "c" to continue) --
○解説
string replace(char oldChar,char newChar)
文字列の oldChar をすべて newChar に置換した新しい文字列を返す。
while ループが一周する毎に String オブジェクトはいくつ登場したでしょうか?
例えば、"はじめまして、こんにちは。" という文字列を入力したとします。
先ずこれで一つ。
次に「。」を「.」に変換した "はじめまして、こんにちは." で二つ。
更に「、」を「,」に変換した "はじめまして,こんにちは." で三つ。
つまり、一周する毎に三つですね。
なぜならば、replace メソッドは新しい文字列を返すからです。
これらの文字列を書き換えることは出来ません。
でも自身に代入してるじゃん?
実は String 型の変数はオブジェクトへのポインタを保存しています。
したがって、ポインタが書き換わることはあっても、オブジェクトそのものは書き換えられません。
それでは、次第に消費されていく、使われていないオブジェクトの為のメモリはどうしましょう?
いずれメモリが足りなくなってしまいます。
でもご心配なく。
メモリが無くなったことが分かると、Javaの仮想マシンは、
使われていないオブジェクトを一生懸命かき集めて、自動的にメモリを空けてくれるのです。
このときの「使われていないオブジェクト( String オブジェクトに限りません)」のことを
「ガーベッジ(ごみ)」と呼び、ガーベッジを集めてメモリを空ける処理のことを
ガーベッジコレクション(ごみ集め)と呼びます。
★参照型
int 型や char 型の変数は基本型と言われています。
その変数には int や char の値が直接代入されています。
それに対して、String 型をはじめとするオブジェクトの変数は参照型と言われています。
その変数にはオブジェクトが直接代入されているわけではなく、
メモリのどこかに存在するオブジェクトを指し示す値(メモリアのアドレス、ポインタ)が代入されているのです。
参照型には、クラス、インターフェース、配列があります。
●問題7-3-3 標準入力の中に指定した文字列を含む行があったら、
その行の番号と内容を表示するプログラムを作って下さい。
○答え
import java.io.*;
public class Find1{
public static void main(String[] args){
if(args.length!=1){
System.out.println("使用法:java Find1 検索文字列 <
検索対象ファイル");
System.out.println("例:java Find1 System < Find1.java");
System.exit(0);
}
String findstring=args[0];
System.out.println("検索文字列は「"+findstring+"」です。");
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
try{
String line;
int linenum=1;
while((line=reader.readLine())!=null){
int n=line.indexOf(findstring);
if(n>=0){
System.out.println(linenum+":"+line);
}
linenum++;
}
}catch(IOException e){
System.out.println(e);
}
}
}
○実行結果
D:\atsushi\Java\List7-7>java Find1 System < Find1.java
検索文字列は「System」です。
6: System.out.println("使用法:java Find1 検索文字列 < 検索対象ファイル");
7: System.out.println("例:java Find1 System < Find1.java");
8: System.exit(0);
11: System.out.println("検索文字列は「"+findstring+"」です。");
12: BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
19: System.out.println(linenum+":"+line);
24: System.out.println(e);
D:\atsushi\Java\List7-7>
○解説
args.length はフィールドです。
args が String 型の配列だからみたいです(?)。
詳しくはまだまだ先の方で(汗)。
args.length は配列の長さ、ここではコマンドラインで入力した引数の個数を表しています。
static void exit(int status)
現在実行している Java 仮想マシンを終了します。
引数はステータスコードとして作用します。
通例、ゼロ以外のステータスコードは異常終了を示します。
args[0] はコマンドラインで入力した最初の引数ですね。
int indexOf(String s)
この文字列の中で、指定された文字列( s )が最初に見つかった位置( 0 以上)を返す。
見つからないときは -1 を返す。
○補足
indexOf メソッドは以下のように4つあります。
int indexOf(int ch)
int indexOf(int ch,int fromIndex)
int indexOf(String s)
int indexOf(String s,int fromIndex)
これらは別のメソッドですが、類似の機能を持っているために同じ名前になっています。
このように、複数のメソッドが同じ名前を使うことをメソッドの多重定義(オーバーロード)と呼びます。
コンパイラは引数の型と個数によって、実際に使われているメソッドを識別します。
引数の型と個数のことをメソッドのシグニチャと呼びます。