Javaメモ > Javaの文字列結合いろいろ Javaの文字列結合いろいろ †Javaでいろいろな方法で文字列結合するメモ。 文字列をそのまま結合する。 †下記のように、文字列を + で結合すると別のStringインスタンスが生成されてしまう為、メモリ、速度の両面でコストが悪くなる。 String strAll = str1; strAll += "と"; strAll += str2; strAll += "と"; strAll += str3; strAll += "を結合"; String.concat を使う。 †速度、メモリ消費とも Stringで結合するよりは良い。 String strAll = str1; strAll.concat("と"); strAll.concat(str2); strAll.concat("と"); strAll.concat(str3); strAll.concat("を結合"); StringBuilder (StringBuffer) を使う。 †String.concat よりさらに良い。(同期が必要な場合のみStringBufferを使用する) StringBuilder sb = new StringBuilder(str1); sb.append("と"); sb.append(str2); sb.append("と"); sb.append(str3); sb.append("を結合"); String strAll = sb.toString(); StringBuilder (StringBuffer) を使う場合に気を付ける事。 †以下のように Stringを文字列結合したものを append してしまうと、 StringBuilder sb = new StringBuilder("文字列1"); sb.append("文字列2" + val1 + "文字列3"); // <-- この部分の結合用に別のStringBuilder が生成される。 String strAll = sb.toString(); やるなら全て append する事。 StringBuilder sb = new StringBuilder("文字列1"); sb.append("文字列2").append(val).append("文字列3"); String strAll = sb.toString(); 普通に文字列結合してもString インスタンスを無駄に生成しない書き方 †文字列を結合する際に、セミコロンで区切らずに結合するとコンパイル時に StringBuilderを使用したイイ感じの結合に変換される。 String strAll = str1 + "と" + str2 + "と" + str3 + "を結合"; 下記の example1 と example2 は等価となる。 public String example1(String s01, String s02, String s03){ String strAll = s01 + "と" + s02 + "と" + s03 + "を結合"; return strAll; } // なぜ String.valueOf を使用するように変換されるのかは謎。 public String example2(String s01, String s02, String s03){ String strAll = new StringBuilder(String.valueOf(s01)) .append("と") .append(s02) .append("と") .append(s03) .append("を結合") .toString(); return strAll; } バイトコードの確認結果は以下の通り。 ただ、コンパイラ(環境)による変換をアテにするよりも明示的にStringBuilderを使用してコーディングした方が良いとは思う。 public java.lang.String example1(java.lang.String, java.lang.String, java.lang.String); Code: 0: new #27; //class java/lang/StringBuilder 3: dup 4: aload_1 5: invokestatic #29; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 8: invokespecial #35; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 11: ldc #60; //String と 13: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 16: aload_2 17: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 20: ldc #60; //String と 22: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 25: aload_3 26: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 29: ldc #62; //String を結合 31: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 34: invokevirtual #42; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 37: astore 4 39: aload 4 41: areturn public java.lang.String example2(java.lang.String, java.lang.String, java.lang.String); Code: 0: new #27; //class java/lang/StringBuilder 3: dup 4: aload_1 5: invokestatic #29; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 8: invokespecial #35; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 11: ldc #60; //String と 13: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 16: aload_2 17: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 20: ldc #60; //String と 22: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 25: aload_3 26: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 29: ldc #62; //String を結合 31: invokevirtual #38; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 34: invokevirtual #42; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 37: astore 4 39: aload 4 41: areturn } |