[[Javaメモ]] > Javaの文字列結合いろいろ
* Javaの文字列結合いろいろ [#vc664b03]
#setlinebreak(on);
Javaでいろいろな方法で文字列結合するメモ。
#contents
** 文字列をそのまま結合する。 [#pe4c683e]
#html(<div style="padding:5px;">)
下記のように、文字列を + で結合すると別のStringインスタンスが生成されてしまう為、メモリ、速度の両面でコストが悪くなる。&br;※コンパイル時に StringBuilder での結合に変換されるが、下記の書き方だと StringBuilderインスタンスをいくつも生成する事になる為、どちらにしても効率が悪い。
#mycode{{
String strAll = str1;
strAll += "と";
strAll += str2;
strAll += "と";
strAll += str3;
strAll += "を結合";
}}
#html(</div>)
** String.concat を使う。 [#r5a5fa5c]
#html(<div style="padding:5px;">)
速度、メモリ消費とも Stringで結合するよりは良い。
#mycode{{
String strAll = str1;
strAll.concat("と");
strAll.concat(str2);
strAll.concat("と");
strAll.concat(str3);
strAll.concat("を結合");
}}
#html(</div>)
** StringBuilder (StringBuffer) を使う。 [#cbaac972]
#html(<div style="padding:5px;">)
String.concat よりさらに良い。(同期が必要な場合のみStringBufferを使用する)
#mycode{{
StringBuilder sb = new StringBuilder(str1);
sb.append("と");
sb.append(str2);
sb.append("と");
sb.append(str3);
sb.append("を結合");
String strAll = sb.toString();
}}
*** StringBuilder (StringBuffer) を使う場合に気を付ける事。 [#cbaac972]
#html(<div style="padding:5px;">)
以下のように Stringを文字列結合したものを append してしまうと、&br;Stringの文字列結合部分が StringBuilder での結合に変換される為、無駄にStringBuilderインスタンスが生成されてしまう。
#mycode{{
StringBuilder sb = new StringBuilder("文字列1");
sb.append("文字列2" + val1 + "文字列3"); // <-- この部分の結合用に別のStringBuilder が生成される。
String strAll = sb.toString();
}}
やるなら全て append する事。
#mycode{{
StringBuilder sb = new StringBuilder("文字列1");
sb.append("文字列2").append(val).append("文字列3");
String strAll = sb.toString();
}}
#html(</div>)
#html(</div>)
** 普通に文字列結合してもString インスタンスを無駄に生成しない書き方 [#s53b697b]
#html(<div style="padding:5px;">)
文字列を結合する際に、''セミコロンで区切らずに結合する''とコンパイル時に StringBuilderを使用したイイ感じの結合に変換される。
#mycode{{
String strAll = str1
+ "と"
+ str2
+ "と"
+ str3
+ "を結合";
}}
#html(</div>)
#html(<div style="padding:5px;">)
下記の example1 と example2 は等価となる。
#mycode{{
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;
}
}}
#html(</div>)
#html(<div style="padding:5px;">)
バイトコードの確認結果は以下の通り。
ただ、コンパイラ(環境)による変換をアテにするよりも明示的にStringBuilderを使用してコーディングした方が良いとは思う。&br;というか、実際には条件分岐が入ったりして、なかなかセミコロンなしで一息で書けるようなケースは少ないように思う。
#mycode{{
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
}
}}
#html(</div>)