第13章 文字列処理(OCJP-Bronze範囲外)

はじめに

文字列に対して様々な処理を行うには標準クラスとして用意されているStringクラスを使います。
この章ではStringクラスを使った文字列の操作について学習していきます。

目次

  • Stringクラス
  • 文字列の連結
  • 文字列の変換
  • 文字列クラスの特徴①
  • 文字列クラスの特徴②
  • 文字列クラスの特徴③
  • StringBuilderクラス
  • 章のまとめ
  • 追加テスト

目標

文字列の操作方法についてマスターすること

Stringクラス

Stringクラスは文字列を扱うクラスです。単に文字列を表すだけではなく、多くの文字列を操作するメソッドがあります。ここではよく使われる代表的なメソッドについて解説いたします。

部分文字列を取り出す

新たにStringExec01クラスを作成し、以下入力してください。

StringExec01.java

package chapter13;

public class StringExec01 {

public static void main(String[] args) {

System.out.println("部分文字列を取り出す");
String s = "yamamoto@al-j.co.jp";
String user = s.substring(0,s.indexOf("@"));
String domain = s.substring(s.indexOf("@") + 1);
System.out.println(user);
System.out.println(domain);
}
}

実行結果

上記はメールアドレスを「@」の前の文字列(ユーザ名)と後ろの文字列(ドメイン)に分ける例です。@が何文字目にあるかをindexOfメソッドで取得し、substringメソッドでその前と後ろの部分を取得します。

public int indexOf(String s) 文字位置を得る

indexOfメソッドは文字列の中から特定の文字列sを探して、その先頭位置を返します。
発見できなければ-1を返します。

public String substring(int from , int to)  部分文字列を得る

substringメソッドは開始位置を第1引数に、終了位置+1を第2引数に指定します。

文字列の連結

StringExec01クラスに以下を追加してください。

StringExec01.java

package chapter13;

public class StringExec01 {

public static void main(String[] args) {

System.out.println("部分文字列を取り出す");
String s = "yamamoto@al-j.co.jp";
String user = s.substring(0,s.indexOf("@"));
String domain = s.substring(s.indexOf("@") + 1);
System.out.println(user);
System.out.println(domain);

//追加(ここから)
System.out.println("文字列の連結");
String email = "";
email = email.concat(user);
email = email.concat("@");
email = email.concat(domain);
System.out.println(email);

System.out.println("大文字に変換");
email = email.toUpperCase();
System.out.println(email);

System.out.println("子文字に変換");
email = email.toLowerCase();
System.out.println(email);
//追加(ここまで)
}
}

実行結果

上記の場合、userと”@”とdomainを連結してメールアドレスを作成しています。また大文字、小文字に変換してコンソールへ出力しています。

文字列を連結する場合にはconcatメソッドを使用します。また、大文字、小文字に変換するにはtoUpperCasetoLowerCaseメソッドを使用します。

public String concat(String s) 文字列の連結

文字列の連結はconcatメソッドを使用します。+演算子で連結できるので、実際はあまり利用されません。しかし、基本的なメソッドなので確認しておきましょう。また以下のようにメソッドを連結して書くことができます。

email = email.concat(user).concat("@").concat(domain);

String toUpperCase() 大文字へ変換

toUpperCaseは英字の小文字を大文字へ変換し、結果を文字列として返します。文字列の中に英字以外が含まれていても構いません。このメソッドは英字にだけ作用します。

String toLowerCase() 小文字へ変換

toLowerCaseは英字の大文字を小文字へ変換し、結果を文字列として返します。文字列の中に英字以外が含まれていても構いません。このメソッドは英字にだけ作用します。

文字列の変換

StringExec01クラスに以下を追加してください。

StringExec.java

package chapter13;

public class StringExec01 {

public static void main(String[] args) {

System.out.println("部分文字列を取り出す");
String s = "yamamoto@al-j.co.jp";
String user = s.substring(0,s.indexOf("@"));
String domain = s.substring(s.indexOf("@") + 1);
System.out.println(user);
System.out.println(domain);

System.out.println("文字列の連結");
String email = "";
email = email.concat(user);
email = email.concat("@");
email = email.concat(domain);
System.out.println(email);

System.out.println("大文字に変換");
email = email.toUpperCase();
System.out.println(email);

System.out.println("子文字に変換");
email = email.toLowerCase();
System.out.println(email);
//追加(ここから)
System.out.println("文字列の変換");
email = email.trim().replace("@", "*");
System.out.println(email);
//追加(ここまで)
}
}

実行結果

public String trim() 前後の空白を取り除いた文字列を作成

trimはもとの文字列の前後から空白を取り除いた文字列を作成して返します。
文字と文字の途中にある空白は残ります。

"   AAA BBB CCC   ".trim()  → "AAA BBB CCC" //途中の空白は残る

public String replace(CharSequence s,CharSequence r) 文字列の変換

replaceは文字列の中に含まれる全ての部分文字列sを文字列rで置き換えた文字列を新たに作成して返します。
CharSequenceは文字列の長さやインデックスに関するメソッド名を定義したインターフェースです。ここではCharSequenceを実装しているクラスであればなんでも良いということです。

文字列クラスの特徴①

String型変数に文字列リテラルを代入して初期化する場合、文字列として作成されます。そして同じ文字列を代入した場合には、JVMは同じ文字列を作成せず、一度作成した同じオブジェクトを使い回します。

String s1,s2;
s1 = "YAMADA"; //新しくオブジェクトが作成される
s2 = "YAMADA"; //新しくオブジェクトが作成されない

上記の場合、s1とs2は同じ参照先が代入されます。つまり s1 == s2 です。

文字列クラスの特徴②

一方、Stringオブジェクトをnew演算子を使って次のように作成した場合は、一般のオブジェクトと同様に毎回新しいオブジェクトが作成され、使い回しはおこなわれません。

String s1,s2;
s1 = "YAMADA"; //新しくオブジェクトが作成される
s2 = new String("YAMADA"); //新しくオブジェクトが作成される

以下StringExec02クラスを作成し、文字列クラスの特徴を確認してください。

StringExec02.java

package chapter13;

public class StringExec02 {

public static void main(String[] args) {

String s1 = "YAMADA";
String s2 = "YAMADA";
String s3 = new String("YAMADA");

//参照を比較する
System.out.println("s1==s2 : " + ( s1 == s2 ));
System.out.println("s1==s3 : " + ( s1 == s3 ));

//文字列を比較する
System.out.println("s1.equals(s2) : " + (s1.equals(s2)));
System.out.println("s1.equals(s3) : " + (s1.equals(s3)));
}
}

実行結果

文字列クラスの特徴③

文字列オブジェクトには初期化時に値を設定したら、以後は一切、内容を変更できないという制限があります。
(Stringクラスは固定長であるという特徴があります。)

String s1;
s1 = "YAMADA"; //新しくオブジェクトが作成される
s1 = "SATO"; //新しくオブジェクトが作成される

上記の場合、s1に”YAMADA”オブジェクトのアドレス情報が代入した後、s1へ”SATO”オブジェクトを代入しようとすると、”YAMADA”オブジェクトの内容が”SATO”へ変更されず、新たに”SATO”オブジェクトが作成されます。

String s1,s2;
s1 = "YAMADA"; //新しくオブジェクトが作成される
s2 = s1.concat("TARO"); //新しくオブジェクトが作成される

上記の場合、s1に”YAMADA”オブジェクトのアドレス情報が代入した後、s2へ”YAMADA”オブジェクトへ”TARO”が連結を代入しようとすると、”YAMADA”オブジェクトの内容が”SATO”へ変更されず、新たに”SATO”オブジェクトが作成されます。

以下StringExec03クラスを作成し、文字列クラスの特徴を確認してください。

StringExec03.java

package chapter13;

public class StringExec03 {

public static void main(String[] args) {

String s1,s2;
s1 = "YAMADA"; //新しくオブジェクトが作成される
s2 = s1.concat("TARO"); //新しくオブジェクトが作成される
System.out.println(s1 == s2);

}
}

実行結果

StringBuilderクラス

Stringクラスが本来固定長であるため、初期化時に値を設定したら、以後は一切、内容を変更できませんでしたが、
StringBuilderクラスは可変長の文字列を扱うクラスで、新しくオブジェクトを作成することなく随時文字列を追加などをすることが出来ます。

以下StringExec04クラスを作成し、文字列クラスの特徴を確認してください。

StringExec04.java

package chapter13;

public class StringExec04 {

public static void main(String[] args) {

StringBuilder sb1,sb2;
sb1 = new StringBuilder();
sb1.append("YAMADA");
sb2 = sb1.append("TARO");
System.out.println(sb1 == sb2);
}
}

実行結果

章のまとめ

以下の要点をしっかり理解してから次の章へ進んでください。

  • Stringオブジェクトで文字列リテラル(”abc”など)で作成することができる。
  • 既に同じ文字列リテラルで作成されたStringオブジェクトがある場合は再利用される。
  • Stringオブジェクトはnew演算子を利用すると毎回新規作成される。
  • Stringオブジェクトの内容は一度初期化されると変更はできない。(Stringクラスは固定長である)
  • StringBuilderクラスは可変長なクラスで、新しくオブジェクトを作成することなく随時文字列を追加することができる。

追加テスト