|
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 } |