String
Stringとは、文字列を扱うためのクラスです。内部に文字列を保持し、それを操作するためのメソッドを提供します。データを保持しているだけの基本データ型(boolean,byte,char,short,int,long,float,double)とは異なりますので気を付けましょう。
java.langパッケージの中にあるため、importすることなく使うことができます。
ここでは、文字列に対して行える様々な操作方法について勉強していきます。
「com.cmps.stringOpe」パッケージを作成し、その中に「StringOperation」クラスを作成してください。
文字列の結合
「+」演算子を使うことで、文字列の連結ができると演算子の単元にてお伝えしましたが、
文字列(String)の結合にStringBuilderクラスを使用する場合もあります。
StringBuilderクラスは文字列操作を行うためのクラスで、併せて使うメソッドによって文字列へ様々な操作が可能となります。
StringBuilderクラスを使用するためにはまず、以下の形式でインスタンス(オブジェクト)を作成します。
StringBuilder オブジェクト名 = new StringBuilder();
実際にStringBuildeオブジェクトを作成して操作してみましょう。
// StringBuilderオブジェクト
StringBuilder textBox = new StringBuilder();
文字列の追加
StringBuilderオブジェクトへ文字列を追加するには、append()を使用します。
オブジェクト名.append(追加したい文字列);
文字列挿入
StringBuilderオブジェクトへ文字列を挿入するには、insert()を使用します。
オブジェクト名.insert(挿入位置,挿入したい文字列);
文字列置換
StringBuilderオブジェクトの文字列を置換するには、replace()を使用します。
オブジェクト名.replace(置換開始位置,置換終了位置,置換したい文字列);
なお、置換の開始位置(開始インデックス)はその値を含みますが、
終了位置(終了インデックス)はその値を含みません。
つまり、1 番目の引数で指定した位置にある文字から 2 番目の引数で指定した位置の一つ前の文字までの部分文字列を、 3 番目の引数で指定した文字列で置換するということです。
また、文字列の長さは置換の結果によって自動的に調整されます。
文字列削除
StringBuilderオブジェクトの文字列を部分削除するには、delete()を使用します。
オブジェクト名.delete(削除開始位置,削除終了位置);
replace()と同じく、開始位置(開始インデックス)の値は含まれますが、
終了位置(終了インデックス)の値は含まれない点に注意してください。
なお、削除位置より後ろに文字列がある場合、自動的に前に詰められます。
// 文字列の追加
textBox.append("こんにちは");
textBox.append("今日の天気は晴れです。");
// 文字列挿入 5文字目直前に挿入
textBox.insert(5, "!");
// 文字列置換 12文字目を「も」に置換
textBox.replace(11, 12, "も");
// 3文字目から5文字目までを置換
textBox.replace(2, 5, "ばんは");
// 文字列削除 1文字目から6文字目まで削除
textBox.delete(0, 6);
System.out.println(textBox);
それぞれのメソッドごとに出力して、文字列がどう変化したのか確認してみてください。
小文字から大文字へ変換(toUpperCase())
半角英語で記載された文字列はtoUpperCase()メソッドを使うことで小文字から大文字に修正することが可能です。
// 出力時に大文字へ修正
String upperString = "test";
System.out.println("パターン1:" + upperString.toUpperCase());
// 出力前に大文字へ修正
upperString.toUpperCase();
System.out.println("パターン2:" + upperString);
// 変換した文字を変数へ格納し、出力
String newString = upperString.toUpperCase();
System.out.println("パターン3:" + newString);
パターン1では、出力時に、「upperString」変数の後ろに「.toUpperCase()」を付けることで出力結果が大文字になっていることが確認できます。
2のパターンではtoUpperCase()の記載はされているものの、出力された文字は小文字のままです。
実は、大文字にするという処理は走っているものの、処理した値をどこにも渡していないので、upperStringには「”test”」と、小文字のままの文字列が入っています。
パターン2の形をなるべく保ったまま大文字で出力したい場合は、大文字にした処理を変数の中に入れることでちゃんと処理されたデータを格納することが出来ます。それがパターン3になります。
大文字から小文字へ変換(toLowerCase())
今度は大文字から小文字への変換を試してみましょう。
// 元の文字列(大文字)
String test = "TEST";
System.out.println("修正前:" + test);
// 小文字を大文字へ修正
String lowerString = test.toLowerCase();
System.out.println("修正後:" + lowerString);
toUpperCase()とは逆で、大文字を小文字へ変換しています。
toUpperCase()とtoLowerCase()は文字の大文字、小文字を行うのに便利なメソッドですが、全ての文字を大文字、小文字にしてしまう点に注意しましょう。
文字列の長さ取得(length()メソッド)
length()メソッドは文字列に格納されている文字の数を数えてくれる処理です。
String sampleString1 = "こんにちは";
String sampleString2 = "Goodbye";
System.out.println(sampleString1.length());
System.out.println(sampleString2.length());
それぞれ5、7と出力されたはずです。
ちなみに、配列の単元にもlengthが出てきたかと思いますが、「length」は配列の長さ(要素数)を返し、「length()」は文字列の長さを返します。
「length」は配列のメンバであるlengthフィールドを利用するため、()は不要となります。
「length()」はString型で定義されているメソッドで、長さの取得にlengthメソッドを用いるため、()が必要となります。
文字列の分割(splitメソッド)
文字列の中にある特定の文字列で分割し、データを配列で受け取りたい場合はsplitメソッドを使います。splitメソッドは、以下のように使用します。
String型変数.split("区切り文字",分割後の要素数)
第1引数の区切り文字は、正規表現で指定します。
第2引数の分割後の要素数は省略することも可能です。省略した場合は、配列の要素数は制限されません。また、配列の終わりの空の文字列がある場合には破棄されます。
splitメソッド使用例
String splitString = "one,two,three";
System.out.println("splitString:" + splitString);
String[] splitArray = splitString.split(",");
for(String split : splitArray) {
System.out.println(split);
}
出力結果
splitStrong:one,two,three
one
two
three
文字列であるsplitStringを「,(カンマ)」で区切り配列に分割しています。
他にも様々な区切り文字で処理可能です。
// 改行コード(\n)
String breakString = "apple\norange\npeach";
String[] fruits = breakString.split("\n");
for(String fruit : fruits ) {
System.out.println(fruit);
}
// タブ(\t)
String tabString = "apple\torange\tpeach";
String[] fruits2 = tabString.split("\t");
for(String fruit2 : fruits2 ) {
System.out.println(fruit2);
}
// 空白
String spaceString = "apple orange peach";
String[] fruits3 = spaceString.split(" ");
for(String fruit3 : fruits3 ) {
System.out.println(fruit3);
}
// ピリオド
String periodString = "apple.orange.peach";
String[] fruits4 = periodString.split(".");
for(String fruit4 : fruits4 ) {
System.out.println(fruit4);
}
空白(半角スペース)は、正規表現を使わず、そのまま半角スペースを引数に渡して使用することも可能です。
4つ目のピリオドですが、引数に「.」を指定してもうまくいきません。
これはsplitメソッドの第1引数は、正確には正規表現で指定するためです。正規表現で「.」は「何か1文字」を表します。
このままではピリオドとして扱われないので、「\\.」と指定する必要があります。
(入力すると「¥¥.」と表示されるかと思いますが、動作はします)
正規表現について詳しくは後の単元で詳しく説明します。
出力結果(見やすくするためにスペースを入れてます)
apple
orange
peach
apple
orange
peach
apple
orange
peach
apple
orange
peach
文字列の連結(concatメソッド)
演算子の単元で文字列の連結について学んだかと思いますが、文字列を連結する方法は他にもあります。
その一つがconcatメソッドです。
String型変数.concat(String str)
concatメソッドは、引数で指定した文字列を「結合対象の文字列の最後に結合」するためのメソッドです。
concatメソッド使用例
String front = "あいう";
String back = "えお";
String concat = front.concat(back);
System.out.println(concat);
「あいう」が格納された変数frontの後ろに「えお」が連結され、「あいうえお」が出力されました。
文字列の連結(joinメソッド)
concatと同じく、文字列の連結で使用できるのがStreamAPIのjoinメソッドです。
String.join("区切り文字", String型変数1, String型変数2, ・・・)
joinは文字列を連結するときに使用するメソッドで、第一引数をデリミタ(区切り文字)とし、第二引数を接頭辞として以降指定された接頭辞の終わりまでの文字列が区切られます。
joinメソッド使用例
String frontString = String.join(",","A","BC","D");
System.out.println(frontString);
出力結果
A,BC,D
第1引数にデリミタである「,(カンマ)」を指定したことで、第2引数以降の文字列が「,」で区切られて出力されています。
また、joinメソッドはString型の配列でも使用することができます。
String[] joinArray = {"EF","G","HI"};
String arrayString = String.join(".", joinArray);
System.out.println(arrayString);
出力結果
EF.G.HI
第1引数に「.(カンマ)」を指定し、第2引数にString型配列を指定して、String型配列の中身を連結しています。
大量のString型配列を連結する場合も、配列ごと一気に連結ができますので、非常に便利です。
文字列の置換(replace()メソッド)
replace()メソッドは、文字列の中から指定した位置から指定した分だけ文字を取り出します。
文章中にある「,(カンマ)」を「、(読点)」に置換したり、「作る」という表記を「創る」に置き換えるような使い方が可能です。
replace()メソッドは以下のように記述します。
対象の文字列.replace(置換される文字列, 置換する文字列)
replaceメソッド使用例
String str = "文字列1\n文字列2\n文字列3\n";
System.out.println(str);
//文字列の「文字列」を「置き換え後」へ置換する
String str2 = str.replace("文字列", "置き換え後");
System.out.println(str2);
文字列「”文字列1\n文字列2\n文字列3\n」の中にある「文字列」を「置き換え後」に置換しています。
「”文字列1\n文字列2\n文字列3\n”」の「\n」は改行コードです。
システム的に見やすくするため、文字列に改行コードを入れることは多々ありますので覚えておきましょう!
文字列の抽出(substringメソッド)
substringメソッドは、指定した文字列から、一部の文字列を取得するメソッドです。
たとえば、「a」から始まり「h」で終わる「abcdefgh」のような文字列データがあったとします。
この場合、「a」の位置は0番目、「h」の位置は7番目となります。
substringを使って、3番目から2文字分の文字列を取得したい場合、
String subString = "abcdefgh";
subString = subString.substring(3,5);
System.out.println(subString);
のように指定して実行すると、文字列「de」が返されます。
substrintは以下のように記述します。
変数(対象の文字列を格納).substring(開始インデックス,終了インデックス)
substringの引数はそれぞれ以下の通りです。
引数1:開始インデックス(この値を含む)、引数2:終了インデックス(この値を含まない)
先ほどは文字を抜き出す形でしたが、今度は引数2を省略して確認してみましょう。
String subString = "abcdefgh";
subString = subString.substring(4);
System.out.println(subString);
結果は「efgh」と表示されます。
これは開始位置「4番目」以降のため、文字列の最後の位置まで取得されています。
substringで後ろから文字を切り出す場合、length()を利用することで可能となります。
String subString = "abcdefgh";
String var1 = subString.substring(subString.length() - 3);
System.out.println(var1);
結果は「fgh」と表示されます。
lengthでsubStringの長さを取得し、その後ろから3番目からを取得しています。
1文字だけ切り出したい場合には、charAtメソッドを使用します。
使い方はsubstringメソッドと同様です。String subString = "abcdefgh";
System.out.println(subString.charAt(3));
上記コードの場合、「d」が表示されます。
前後の空白を削除(trimメソッド)
「trim」とは英語で「切り取る」という意味です。
trimメソッドは、文字列の先頭と末尾から余計な空白と制御文字をすべて削除します。
ここでいう余計な空白とは「半角スペース」や「Tab」などのことを指します。
取得した文字列から不必要な空白や文字を取り除くプログラムの処理はよく使用されます。ぜひ習得しておきましょう。
trimメソッド使用例
String trim = " あいうえお "; // 前の余白がタブ、後ろの余白が半角スペース2個
System.out.println("削除前:" + trim + "");
System.out.println("削除後:" + trim.trim() + "");
trimでは半角スペースだけでなく以下のものが取り除けます。
“\t”(タブ)
“\r”(改行)
“\n”(リターン)
基本的に文字列の前後のタブや半角スペースの削除に用いられます。
文字列間の空白や全角スペースは削除できませんので注意しましょう!
前後の空白(全角・半角)を削除(stripメソッド)
stripメソッドは、trimメソッドとほぼ同じ使い方が出来るメソッドで、stripメソッドは前後の全角、半角のスペースや改行、タブを削除します。
なので、全角スペースを削除したい時にはstripメソッドを使うようにしましょう。
また、strip メソッドは文字列の先頭と末尾の空白文字を取り除きますが、文字列の先頭だけの空白文字を取り除く stripLeading メソッドと、文字列の末尾だけの空白を取り除く stripTrailing メソッドがそれぞれ用意されています。
stripメソッド使用例
String strip = " あいうえお "; // 前の余白が全角スペース、後ろの余白が半角スペース2個
System.out.println("削除前:" + strip + "");
System.out.println("削除後:" + strip.strip() + "");
System.out.println("先頭のスペース削除:" + strip.stripLeading() + "");
System.out.println("末尾のスペース削除:" + strip.stripTrailing() + "");
文字列の整形(String.format)
String.formatは引数に指定した文字列(書式)を元にルールに沿った文字列を返すというメソッドになります。
String.formatは以下のように記述します。
String.format(書式文字列, 値)
第1引数 :生成する文字列のフォーマットを指定
第2引数〜:生成する文字列や値を指定
String.formatでフォーマットするには型指定子を使います。「%s」には文字列を、「%d」には数値を代入することができます。
型指定子の種類
| 型指定子 | 説明 |
|---|---|
| % | %文字。型指定子の先頭に指定します。 |
| b | 真偽値。 |
| c | Unicode文字。 |
| d | 10進数の整数。 |
| f | 10進小数点数。 |
| e,E | 浮動小数点数形式の10進数。 |
| s | 文字列。 |
型指定子には様々な種類がありますので、詳しく知りたい方は下記サイトを参照してください。
【5分で理解】JavaのString.formatの使い方まとめ
String.format使用例
String stringFormat = "%sの値段は%d円です。";
String item = "apple";
Integer val = 100;
String result = String.format(stringFormat, item,val);
System.out.println(result);
実行結果を見てみると、「appleの値段は100円です。」と表示されたと思います。
また、データを決められた桁数で揃えたいとき、formatを使用すれば、桁数を0で揃えることができます。
0 埋めをする場合は、型指定子%の後に 0(パティング指定子) 、作成したい桁数 (表示幅指定子) 、d を指定します。
例えば、「 %08d 」のように記述すると桁数が8桁になるまで、「0」で埋めることができます。
実際に 使用して 0 埋めをしてみましょう。
Integer sampleInt = 1111;
System.out.println(String.format("%08d", sampleInt)); // 00001111
文字列として0埋めをしたい場合、スペースを埋めた後replaceを使い0へ変換しましょう。
String sampleStr = "1111";
System.out.println(String.format("%8s", sampleStr).replace(" ", "0"));
このように、String.formatは引数に指定した値を指定の形式にフォーマットした文字列を取得することができます。
文字列の比較(String.contains(String s))
if文の単元にてequalsを用いた、文字列の完全一致について取り扱いました。
ここでは、文字列の部分一致の比較についてご紹介します。
String.contains()の使い方ですが、比較元となる文字列変数にString.contains(比較対象の文字列)を入れることで記載出来ます。
String.contains(String s)使用例
String string = "こんにちわ。こんばんわ。";
String checkS1 = "こんにちわ";
// .contains(比較対象の文字列)
if (string.contains(checkS1)) {
System.out.println("結果:該当");
} else {
System.out.println("結果:該当なし");
}
上記の処理では、stringの文字列に対して「こんにちわ」という文字列が入っているかを確認しています。文字が含まれているので「該当」が出力されます。
String words = "aaa";
String checkS2 = "";
if (words.contains(checkS2)) {
System.out.println("結果:該当");
} else {
System.out.println("結果:該当なし");
}
2つ目の処理では比較対象に「””」を使っています。
これは空文字といい、変数の中に1文字も存在しない文字の塊と思ってください(後の単元にて取り扱います)。
今回の比較では”aaa”ではaの文字の間に「””」が存在しているため、この状態でも含まれている、に該当してしまいます。
イメージとしては空文字を仮に「△」に置き換えると、
「△」という文字列の塊を「△a△a△a△」に含まれているかを比較して、「△」があるので、含まれている、という扱いになります。
エラーが出ない分検知に時間がかかって厄介です。
String text = "aaa";
String checkS3 = null;
if (text.contains(checkS3)) {
System.out.println("結果:該当");
} else {
System.out.println("結果:該当なし");
}
この処理は比較対象に「null」を使っています。
先ほどの「””」では存在しない文字の塊とお伝えしましたが、「null」は変数の中には本当に何も入っていません。
そのため、比較をしようとした時、String.contains()の中で実行される処理の中で存在しない値を使用できないとエラーを返します。
この時に出力されるエラーは「NullPointerException」です。
「NullPointerException」は、値を参照(使おう)する際、値が入っていなければ発生するエラーです。
コンソールのエラー文を見ると「Main.java:○○」このような表示があるかと思われます。
こちらをクリックすると、エラーの発生源を確認できます。
今回では以下の行が該当します。
if (text.contains(checkS3)) {
s3には”aaa”の文字が入っているので、checkS3でエラーが出力されたと判断できます。
練習問題
「com.cmps.stringOpe」パッケージ内に「StringQuestion」クラスを作成してください。
問1:適当な国名がカンマ区切りで5か国以上並んだ文字列を作成し、それを国名毎に分割された配列に変換してください。
問2:「name:田中,age:24,sex:男 name:中村,age:54,sex:女 name:鈴木,age:18,sex:男」の文字列を人毎の項目毎に分割された多次元連想配列にしてください。
問3:「2022-06-03 13:43」を「2022/06/03 13:43」にしてください
問4:全角・半角スペースを削除しましょう。
問5:「おはようございます。今日も元気で頑張ります!よろしくお願いいたします。」の文字列を使用して「おはよう。今日も元気です!よろしく。」とsubstringメソッドを使用して表示してください。
問6:「 HelloWorld 」の前後の空白を削除してください。
問7:「東京 タワー 」の後ろのみ空白を削除してください。
問8:「ABCD」を左寄せでそれぞれ6桁、7桁、8桁で0埋めして表示してください。
練習問題のヒント
問2:
文字列をsplitを用いて、「 」(スペース)「,」(カンマ)「:」(コロン)で分割していきます。
人ごとの配列を作成し、それを一つの大きな配列に入れ込みます。
ただし、splitは配列に対して使用ができないため、splitで作成した配列を拡張for文を使い文字列として取り出せるようにしてから、再びsplitで分割し配列にします。この工程を分割したい数だけ行います。
最終的に以下のような出力になれば正解です。
[{sex=男, name=田中, age=24}, {sex=女, name=中村, age=54}, {sex=男, name=鈴木, age=18}]
問8:
文字列の0埋めは直接行う事が出来ないので、
①左詰めした文字列を作成
②replaceを使い、空白部分を0へ変換
このようなプロセスで解くことが出来ます。
