Javaで文字を扱う際に、切り出した文字や配列の要素をつなげることがあります。そこで利用されるメソッドが「concat」です。
JavaでStirngの型を扱う際は、文字列の結合にいくつかのメソッドの選択肢があり、concatメソッドにも適した使用場面や効率化できる部分があります。
そこで本記事は、concatメソッドと他のメソッドとの違いや使い方、活用方法などを紹介します。
目次
1.Javaの「concat」とは?
concat(コンカチ)とは、「concatenation(コンカチネーション)」を短くした呼び方です。直訳では「連結」を意味し、Javaのプログラミングでは文字列を連結するメソッドとして使われます。
Stringクラスにおけるメソッド「concat」の特徴
concatメソッドは、Stringクラスのメソッドです。結合したい文字列をメソッドの左右に入れるだけで使えます。
具体的には、concatメソッドのプログラム実行は、「レシーバー」と「引数」を使って行います。例えば、「A.concat(B)」で「AB」と結合する場合、Aがレシーバー、Bが引数です。
仕組みとしては、レシーバーに入れた文字列の後ろに、引数の文字列をくっつけます。そのため、「BA」ではなく、「AB」となります。
連結メソッド「append」との違い
concatと似た連結メソッドに「append」メソッドがあります。concatとappendの大きな違いは、concatが新規のオブジェクトを作り、appendは作らないことです。
Stringクラスでは基本的に文字列を一度作成すると変えられない「不変」の性質をもちます。そのため、元の文字を変えずに元の文字列をそのまま反映した新たな結合文字列を生み出します。
appendの場合、クラスがStringBuilderかStringBufferのため、対象となる文字列そのものを変えることができます。「A.append(B)」なら「A」に「B」を追加して「A = AB」にしているのです。つまり、Aのレシーバーを直接的に書き換えています。この点も違いの1つです。
オブジェクトを生み出すメリット・デメリット
オブジェクトを生み出すことは、それ自体にメリット・デメリットがあります。まず、オブジェクトを作る場合、文字列が変わらないため、繰り返し使えることがメリットです。appendでは元のオブジェクトを保持しないため、処理後は変更値が適用されます。
一方、オブジェクトの生成には時間がかかるため、単純に時間がかかりパフォーマンスが悪くなることがあります。したがって、短い文字列を一度だけ結合させる場合はconcatを使用し、たくさんの文字列を何度も同じ文字列に結合したい場合はappendを使うなど、使い分けることが必要です。
「concat」と「+」の違い
concatのような結合は、プラス演算子「+」の使用でも代替可能です。プラス演算子「+」は、記号を使うだけで簡単に左右を結合することができます。
使用場面がconcatよりも広く、数値や「null」との結合も可能です。ただし、使用できる範囲が広すぎるため、文字列型以外に変換されることがあるなど、想定外の挙動や型変更が発生することもあります。
型を文字列に限定して、突発的な型の変更を防ぐには、concatのように使用場面と型が限られているメソッドのほうが開発時の安全面や保守管理で効率的なこともあるのです。
joinとの違い
joinは、複数の文字列(配列・collection)に対して繰り返し区切りを付けられる結合メソッドです。カンマ「,」などを単語ごとに入れたいときなどに便利です。文字列ごとに入れる区切りに使う記号や文字列は、「デリミタ」という区切りの指定部分に設定することで使えます。
しかし、concatでは文字をそのままつなげることが主要な使い方ですから区切りが必要ありません。そのまま代替となる結合方法ではないところに違いがあります。
ちなみに、joinは内部にStringBuilderを使用してオブジェクトを生成しており、処理速度はappendより少し遅くconcatより圧倒的に早いのが特徴です。この点だけを見ると、他のメソッドと比べてconcatのみが処理速度の面で劣っています。
2.Javaにおける「concat」の使い方
以下では、Javaで使われるconcatメソッドの使い方を紹介します。
文字列をつなげる基本の使い方【2単語のみ】
まずは、別々の文字をそのまま連結する場合です。例えば、「アップル」「パイ」をつなげて「アップルパイ」と1つの文字列にしたい場合を考えましょう。
文字列をオブジェクトにそれぞれ格納して型の宣言を行い、「.concat()」に2つの変数を入れてメソッドで結合します。
public class ConcatExample { public static void main(String[] args) { String str1 = "アップル"; String str2 = "パイ";
String result = str1.concat(str2); System.out.println(result); } } |
上記では、あえて繰り返し利用を想定して、変数に「アップル」と「パイ」を格納しています。リテラル文字列でも「"アップル".concat("パイ")」のように直接メソッドを呼び出すことも可能です。
しかし、直接入れるだけなら、他のメソッドのほうが処理速度は優れているので、処理速度が劣ることを考えると、変数でconcatメソッドを使うことが基本の形です。
Javaの「concat」で3つ以上の文字列を結合する【複数文字列】
次に、文字列が3つ以上のケースです。基本的なメソッドの形は同じで、使い方のみ覚えれば3つ以上にもすぐに対応できます。
それが、「A.concat(B).concat(C)」の形です。これで文字列が「ABC」と結合されます。例えば、「茶色いアップルパイ」の3単語結合は、以下のように作ります。
まず、「茶色い」「アップル」「パイ」を連結するために、レシーバーに先頭の文字列「茶色い」、1つ目のconcat引数に「アップル」、2つ目の引数に「パイ」を入れて「"茶色い".concat("アップル").concat("パイ")」とするのです。結合した結果、3つが横に並ぶ出力結果が得られます。
ただし、これだと変数に入れていないため、再利用できません。そこで、以下のソースコード例では、3つ以上の文字列ときにも、先の例と同じように変数に格納して結合する方法としています。
public class ConcatExample { public static void main(String[] args) { String str1 = "茶色い"; String str2 = "アップル"; String str3 = "パイ";
String result = str1.concat(str2).concat(str3); System.out.println(result); } } |
上記の例では、3つの単語のパターンですが、数が増えた分だけメソッドを「A.concat(B).concat(C).concat(D)…」と増やすだけなので、4単語、5単語…と増えた場合でもこの方法で対応できます。
空白を入れるときの対処
「アップルパイ」は日本語を結合させているため、「空白(スペース)」が必要ありません。しかし、英単語は場合によって半角空白(半角スペース)の「 」が必要です。
例えば、「apple pie」がその1つです。その際は、半角空白「" "」を1つの文字列として、オブジェクトに追加格納し、3つの文字列としてつなげて利用します。
String str1 = "apple"; String str2 = " "; String str3 = "pie"; |
以上の半角空白を含む3つの単語を用意して「str1.concat(str2).concat(str3);」とするわけです。
単語に半角を含めて「apple 」「 pie」としても同じ結果となりますが、文字列の再利用性を踏まえると、この方法はおすすめできません。「" "」を追加で用意するのがベストです。一度変数を入れれば、何度でも「" "」として使えるため、変数もそれ以上増えません。
また、数値や日付の文字に空白をフォーマットに合わせて自動で入れたい場合は、動的な数値に柔軟な対応ができる「String.format()」メソッドがおすすめです。
「String str = String.format("%-4d", 250)」は、整数・左揃え・桁数のフォーマットを指定できます。そのため、指定に合わせて自動的に空白(スペース)を入れることができます。
配列内の要素(文字列)を結合する方法
配列の場合は、concatを使う前に配列の宣言や文字列の値を入れます。それをインデックス(0から始まる番号付け)の数字で指定して結合します。
public class ConcatArrayExample { public static void main(String[] args) { String[] foodWords = {"アップル", "パイ"}; String result = foodWords[0].concat(foodWords[1]); System.out.println(result); } } |
この例の場合も、{"アップル", "パイ", "スイカ"}のように結合数が増える場合は「foodWords[0].concat(foodWords[1]).concat(foodWords[2])」のようにインデックスの数字を1つ足しながら増やしていけば、対応可能です。
ただし、要素数が多い場合やあらかじめ要素数が不明な場合は、ループを使用するか、String.join()メソッドやStringBuilder、StringBufferを使用するとより効率的です。
関連記事
Javaプログラミングで何ができる?始め方や基本文法、練習サイト5つを紹介
Java初心者ガイド|Java学習のロードマップと効率良い勉強方法を解説
3.Javaの「concat」をログ管理に活用する事例
使い方がわかったら、今度はそれを応用してシステム構築やアプリ開発のログ管理に使用する活用方法です。以下に2つの事例を紹介します。
取得するログ情報を前提としたインフォメーション文面の表示
まずは、シンプルなconcatメソッドの方法を使って、取得したログメッセージを1つの文字列の塊としてセンテンス出力する方法です。
例えば、ログが記録されているファイル「log.txt」を用意し、その中から「user_001」のアクションをconcatメソッドで結合させて表示させる例が以下です。
log.txt:
userId: user_001 action: ログイン |
上記のファイルは、「userId」「action」の順で改行しています。
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException;
public static void main(String[] args) { String logFilePath = "log.txt"; String userIdToSearch = "user_001"; String action = ""; boolean matchFound = false;
String line; while ((line = br.readLine()) != null) { line = line.trim(); if (line.startsWith("userId:")) { String foundUserId = line.split(":", 2)[1].trim(); if (foundUserId.equals(userIdToSearch)) { String nextLine = br.readLine(); //次の行を指定 if (nextLine != null && nextLine.trim().startsWith("action:")) { action = nextLine.split(":", 2)[1].trim(); matchFound = true; break; } } } } } catch (IOException e) { System.out.println("ログファイルの読み込みエラー: " + e.getMessage()); } if (matchFound) { String logMessage = "[インフォメーション] ".concat("ユーザーID: ").concat(userIdToSearch) .concat(" が ").concat(action) .concat(" を実行しました。"); System.out.println(logMessage); } else { System.out.println("指定された userId のアクションが見つかりませんでした。"); } } } |
この例のように、「br.readLine()」を指定して次の行を読み込めば、userIdとアクションを紐付けした状態で探すことができます。その上で、探し出したアクションを変数に代入し、concatメソッドを使って一文にするわけです。条件に合わせた必要なログメッセージを作り出せるでしょう。
concatをループさせて結合する
次は、拡張for文を使った活用例です。ログのエラーメッセージに対し、文字列を結合してを出力する中で、拡張for文を使ってエラーの要素の個数だけ結合を繰り返します。
public class ValidationErrorFormatter { public static void main(String[] args) { String[] validationErrors = { "ユーザーIDが未入力です", "パスワードが8文字未満です", "メールアドレスの形式が正しくありません", "生年月日が未来日になっています" };
for (String error : validationErrors) { formattedMessage = formattedMessage.concat("・").concat(error).concat("\n"); }
} } |
上記は「\n」で改行を入れ「・」で箇条書きにしている工夫を入れているため、エラーごとに結果を確認しやすくなっています。これを参考に、ループ結合を使いこなすことがおすすめです。
関連記事
【Javaアプリ開発|初心者必見】手順やおすすめの練習方法を教えます!効率化の手段やアプリ例も解説!
【Java】for文の使い方|拡張for文やforEach・配列/リスト操作・省略形を解説
4.Javaのconcat使用でよくある質問
ここではJavaのconcatメソッドを使う際に生じる疑問・質問に回答します。
Javaのconcatメソッドにnullは使用できない?
Javaで「concat」を使う場合、文字列のみを連結します。そのため、intなどの「数値」や「null」は、結合することができません。
特にnullは、間違って入れてしまうと結合できないだけでなく、例外のエラー「NullPointerException」が発生して、Javaでは実行ができません。これは、Javaがnullを入れた変数をオブジェクト参照ができないためです。
ただし、nullやnullの変数を「String.valueOf()」を使って引数に入れた場合は、自動的に「"null"」の文字列として扱われます。そのため、nullの場合でも文字列のnullが追加として処理は一応可能です。
つまり、「null.concat(str)」はNullPointerExceptionが発生しますが、「str.concat(String.valueOf(null))」のように非nullオブジェクトのconcatメソッドを呼び出し、引数にString.valueOf(null)を使用すればOKということです。
もちろん、文字列の連結にnullを足すことはそもそも想定されないため、nullは入れないのが基本です。空文字のつもりでnullを入れることがある場合は、nullチェック時に空文字に変換するようにします。
実行時にnullのエラーをどうしても避けたいケースや想定上nullが入る余地がある実装のケースは、StringUtilsのisEmptyメソッドでnullを確認するなど、必要なnullチェックを事前に入れてエラーを回避するようにしましょう。
Javaで文字列の切り出しメソッド「Substring」って何?
concatメソッドが文字を連結させるのに対し、「Substring」メソッドでは、文字列を切り出しすることができます。
引数を1つ指定する場合(指定位置から最後まで)と、2つ指定する場合(開始点店から終了点まで)とで切り出す方法が変わります。先の活用法でログのサーチに使用したようにindexOfメソッドを使ってある文字の出てくる点を調べられます。
後は、それを基準にSubstringメソッドで任意の情報を取得し、欲しい文字列だけ切り出しできます。
関連記事
Java「equals」とは?否定・複数条件の比較・文字列・nullの使い方や注意点を解説
5.まとめ
今回は、Javaでconcatメソッドを使用して文字列を結合する方法について、他のメソッドとの違いや使い方、活用方法などを解説しました。concatメソッドは、処理速度は他のメソッドに劣る反面、nullの使用への制限や文字列の限定、オブジェクト新規生成による再利用性に優れています。
ログを取得してそれを文字列結合して出力もできるため、活用の幅は広いでしょう。ただし、オブジェクトを生成しないほうが都合が良い場合や速度重視の場合などでは不利です。場面に応じて別のメソッド選択が必要となります。
本記事が皆様にとって少しでもお役に立てますと幸いです。
「フリーランスボード」は、数多くのフリーランスエージェントが掲載するITフリーランスエンジニア・ITフリーランス向けの案件・求人を一括検索できるサイトです。
開発環境、職種、単価、稼働形態、稼働日数など様々な条件から、あなたに最適なフリーランス案件・求人を簡単に見つけることができます。
単価アップを目指す方や、自分の得意なスキルを活かせる案件に参画したい方は、ぜひ「フリーランスボード」をご利用ください。