【Java】文字列操作関連
本稿は、文字列操作関連で私が便利だと思った機能に絞り、それぞれ紹介します。
文字列操作は、ほとんどの分野で必須なので、ある程度操作できるようになっておきましょう。
もちろん、ここで紹介する以外にも便利なメソッドがたくさんあるので、是非Stringクラスのドキュメントを読んでみてください。
- 文字列の値が同じかどうか比較するequals
- 文字列の先頭が指定した文字列かどうか判定するstartsWith
- 文字列の後ろが指定した文字列かどうか判定するendsWith
- 文字列の長さを取得するlength
- アルファベットを大文字にするtoUpperCase
- アルファベットを小文字にするtoLowerCase
- 指定文字列の登場位置を数値で取得するindexOf
- 指定文字列の登場位置を後方から検索し、数値で取得するlastIndexOf
- 文字列の置き換えをするreplace
- 文字列の抜き出しをするsubstring
- 文字列の分割をするsplit
- 複数の文字列を区切り文字で結合するjoin
- 文字列結合を効率化するStringBuilder
equalsメソッド
おなじみequalsメソッドでの文字列値比較です。
public class Test{ public static void main(String[] args){ String s = "猫"; System.out.println("猫".equals(s)); System.out.println("犬".equals(s)); } }
true
false
余談・・・
「s.equals(“猫”)」と書いても基本的に同じことができますが、私は「”猫”.equals(s)」のほうをお勧めします。
理由はぬるぽ落ちしないからです。
Stringクラスのソースを見ればわかるのですが、s.equalsではsがnullの場合、ぬるぽがその時点で発生しますが、”猫”.equalsならsがnullだったとしても、equalsメソッド内部でnull instanceof Stringが実行され、次に処理を行わず、falseを返すようになっているんですね。
もちろんnullと固定値をtrueにしたい場合には使えませんが、大抵はfalseにしたいことが多いと思うので、nullチェックが不要な、固定値.equals(変数)の書き方を積極的に使うと無駄な工数をかけなくて済みますしソースも短くなります。
startsWithメソッド
文字列の先頭が指定した文字列で始まるかどうか、判定します。
public class Test{ public static void main(String[] args){ String s = "ABCD"; System.out.println(s.startsWith("ABC")); System.out.println(s.startsWith("ABD")); } }
true
false
endsWithメソッド
文字列の先頭が指定した文字列で始まるかどうか、判定します。
public class Test{ public static void main(String[] args){ String s = "ABCD"; System.out.println(s.endsWith("ABC")); System.out.println(s.endsWith("BCD")); } }
false
true
lengthメソッド
文字列の長さを取得できます。
public class Test{ public static void main(String[] args){ String s = "ABCあD"; System.out.println(s.length()); System.out.println("スーパー関西人".length()); } }
5
7
toUpperCaseメソッド
アルファベットを大文字に変換できます。
public class Test{ public static void main(String[] args){ String s = "Abcあ真D"; System.out.println(s.toUpperCase()); } }
ABCあ真D
toLowerCaseメソッド
アルファベットを小文字に変換できます。
public class Test{ public static void main(String[] args){ String s = "Abcあ真D"; System.out.println(s.toLowerCase()); } }
abcあ真d
indexOfメソッド
先頭から文字列を検索し、最初に登場する文字列の番号を返します。
一致しなかった場合は-1を返します。
public class Test{ public static void main(String[] args){ String s = "sAbあかさAbX"; System.out.println(s.indexOf("Ab")); //4番目の文字列から検索開始したい場合 System.out.println(s.indexOf("Ab",3)); //検索に引っかからない System.out.println(s.indexOf("AGb")); } }
1
6
-1
後述するsubstringメソッドと一緒に使用することで、特定の文字列を抜き出したりできます。
指定文字列を含むかどうかも判定できますし、汎用性の高いメソッドです。
まあ、指定文字列を含むかどうかの比較はcontainsメソッドでもできるんですけどね・・・
lastIndexOfメソッド
文字列終端から検索し、最初に登場する文字列の番号を返します。
一致しなかった場合は-1を取得します。
public class Test{ public static void main(String[] args){ String s = "sAbあかさAbX"; System.out.println(s.lastIndexOf("Ab")); //4番目の文字列から先頭方向へ検索 System.out.println(s.lastIndexOf("Ab",3)); //検索に引っかからない System.out.println(s.lastIndexOf("AGb")); } }
6
1
-1
replaceメソッド
指定した文字列全てを別の文字列で置き換えます。
public class Test{ public static void main(String[] args){ String s = "sAbあかさAbX"; System.out.println(s.replace("Ab","ウッひょー")); } }
sウッひょーあかさウッひょーX
substringメソッド
文字列の抜き出しができます。
public class Test{ public static void main(String[] args){ String s = "sAbあかさAbX"; //文字列の7番目から最後まで抜き出し System.out.println(s.substring(6)); //文字列の4番目から6番目までを抜き出し System.out.println(s.substring(3, 6)); } }
AbX
あかさ
splitメソッド
文字列をString配列に分割できます。
public class Test{ public static void main(String[] args){ String s = "100,200,300"; String[] spl = s.split(","); for ( String n : spl ) { System.out.println(n); } } }
100
200
300
気を付けなければならないのが、指定する文字列は正規表現だということです。
正規表現とは文字列を曖昧検索するための手段です。例えば「A+」を表す正規表現はAが一文字以上続くことを表します。
正規表現について興味がある方はこちらのサイト等で勉強してください。
「+」文字等の正規表現文字は通常の記述では正規表現として扱われてしまうので分割できません。
では、「A+」区切りで分割したい場合どうするのかというと、こうします。
public class Test{ public static void main(String[] args){ String s = "100A+200A+300"; String[] spl = s.split("A\\+"); for ( String n : spl ) { System.out.println(n); } } }
100
200
300
ここで、でてきた「\\」(円マークまたはバックスラッシュ)ですが、正規表現文字を通常の文字として読み込ませるための文字です。これを一般的には「エスケープする」とか言われたりします。
正規表現を普通の文字列として読み込ませたい場合は正規表現文字の直前に「\」文字を入れるのですが、Javaの文字列「””」内部にも「\」でエスケープできるようになっています。
よって、Javaの文字列内に「\」を入れたい場合は「\\」と記述する必要があるのですね。
joinメソッド
文字列配列を、指定した文字列区切りで結合した文字列に変換します。
public class Test{ public static void main(String[] args){ String[] s = {"100","200","300"}; System.out.println(String.join(",", s)); } }
100,200,300
カンマ区切りで、データを保存するようなセーブファイルを作成する時とかに使えるかもしれませんね。
StringBuilderクラス
Javaで文字列結合は「+」演算子が利用されますが、複数の文字列をたくさん結合していきたい場合は「+」演算子での結合はやめたほうがいいです。
理由は非効率だからです。
使い方はこんな感じです。
public class Test{ public static void main(String[] args){ StringBuilder sb = new StringBuilder(); sb.append("犬"); sb.append("猫"); sb.append("サル"); String s = sb.toString(); System.out.println(s); } }
犬猫サル
学生時代に自作マップエディタを開発している時に書き出しファイルにCSV形式を採用していたのですが、マップが広くなると書き出し速度が異常に遅くなる現象に遭遇しました。
その時から、たくさんの文字列を結合する時は必ずStringBuilderを使用するようにしています。
無理して使用する必要はなく、文字列結合を少しするくらいなら、普通の+で構いません。
それでは最後に文字列結合による速度比較ができるサンプルを紹介します。
public class Test{ public static void main(String[] args){ //起動時のほうが処理が遅くなる為ダミー処理(効果あるかわからん) for ( int i = 0;i < 1000;i++ ); final int testNum = 1000; long t = System.currentTimeMillis(); StringBuilder test1 = new StringBuilder(); for ( int i = 0;i < testNum;i++ ) test1.append("A"); System.out.println(test1.substring(0,10)); System.out.println("StringBuilder="+(System.currentTimeMillis()-t)+"ミリ秒\n"); long t2 = System.currentTimeMillis(); String test2 = ""; for ( int i = 0;i < testNum;i++ ) test2+="A"; System.out.println(test2.substring(0,10)); System.out.println("+演算子="+(System.currentTimeMillis()-t2)+"ミリ秒"); } }
AAAAAAAAAA
StringBuilder=1ミリ秒
AAAAAAAAAA
+演算子=16ミリ秒
表示文字列は結果が長すぎると見にくいと思ったので、あえてsubstringメソッドで先頭10文字のみ表示させました。
気にしないでください。
Aの文字列を1000回結合してみましたが、やはりStringBuilderが高速ですね。
当然文字列が多くなると速度差がかなり出てきますので、たった15ミリ秒程度の差だと思わないほうがいいです。
興味のある方はtestNumを修正して結合回数を増やして試してみてください。
・・・ちなみに、200000回結合すると私の環境では3000ミリ秒以上の差が出ています。
ディスカッション
コメント一覧
まだ、コメントがありません