String型

<概要> 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) --

○解説

public string replace(char oldChar,char newChar)  //String クラス
 文字列の oldChar をすべて newChar に置換した新しい文字列を返す。

※public はまだ気にしないで下さい。

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 はフィールドです。
フィールドとは、C++言語で言うところのクラスのメンバー変数のようなものです。
んー?String クラスにはそんなフィールド無いぞ?
実は length は全ての配列が保持するフィールドです。
Java言語では配列はクラスのように扱われるのですが、
詳しくは配列やクラスなどを学んだときに解説します。
args.length は配列の長さ、ここではコマンドラインで入力した引数の個数を表しています。

public static void exit(int status)  //System クラス
 現在実行している Java 仮想マシンを終了します。
 引数はステータスコードとして作用します。
 通例、ゼロ以外のステータスコードは異常終了を示します。

※static はまだ気にしないで下さい。

args[0] はコマンドラインで入力した最初の引数です。

public int indexOf(String s)  //String クラス
 この文字列の中で、指定された文字列( s )が最初に見つかった位置( 0 以上)を返す。
 見つからないときは -1 を返す。

○補足

indexOf メソッドは以下のように4つあります。

public int indexOf(int ch)  //String クラス
public int indexOf(int ch,int fromIndex)  //String クラス
public int indexOf(String s)  //String クラス
public int indexOf(String s,int fromIndex)  //String クラス

これらは別のメソッドですが、類似の機能を持っているために同じ名前になっています。
このように、複数のメソッドが同じ名前を使うことをメソッドの多重定義(オーバーロード)と呼びます。
コンパイラは引数の型と個数によって、実際に使われるメソッドを識別します。
引数の型と個数のことをメソッドのシグニチャと呼びます。


戻る / ホーム