Maverickでエンジニアをしているはぎーです。 初心者による初心者のためのJavaのお話。 今回は、今更なのですが皆大好きString[文字列結合]のお話です。
文字列結合
文字を連結させる時ってどうやってますか?
String str = "文字列"; String str2 = "結合";
str = str + str2; System.out.println(str);
str += str2; System.out.println(str);
str = str.concat(str2); System.out.println(str);
StringBuffer buffer = new StringBuffer(); buffer.append(str).append(str2); System.out.println(buffer.toString());
※buffer.append(str + str2)としない事!
StringBuilder builder = new StringBuilder(); builder.append(str).append(str2); System.out.println(builder.toString());
※builder.append(str + str2)としない事!
パフォーマンス
StringBufferとStringBuilderが圧勝!
\ | + | += | concat | StringBuffer | StringBuilder |
---|---|---|---|---|---|
1 | 7050531985 | 6149053506 | 1668302159 | 5035470 | 3535256 |
2 | 1744332285 | 1767654100 | 1684246677 | 2726805 | 3031675 |
3 | 1893079563 | 1867336491 | 1949670518 | 1650526 | 2497395 |
4 | 1937411127 | 1784706081 | 1828080242 | 759785 | 700876 |
5 | 1910195345 | 1962878011 | 1775268037 | 1183416 | 1094431 |
6 | 1884419177 | 2026627222 | 1771173228 | 1151601 | 1001537 |
7 | 1810280168 | 1772959238 | 1679123452 | 686984 | 665790 |
8 | 1795469468 | 1859131489 | 1743807530 | 959268 | 698827 |
9 | 1620505270 | 1697486759 | 1703181588 | 807823 | 709243 |
10 | 1794568987 | 1843452735 | 1736388097 | 1035004 | 693362 |
平均 | 1848002118 | 1848410674 | 1735677526 | 1131273 | 1117052 |
※それぞれ文字列結合100000回を10セット
※単位 = ナノ秒
※平均 = 大小2位ずつを除く平均
public class StringTest { private static final int LOOP = 100000; public static long stringPlus() { long start; long stop; // String(+) String str1 = ""; start = System.nanoTime(); for (int i = 0; i < LOOP; i++) { str1 = str1 + "A"; } stop = System.nanoTime(); return stop - start; } public static long stringPlusEqual() { long start; long stop; // String(+=) String str2 = ""; start = System.nanoTime(); for (int i = 0; i < LOOP; i++) { str2 += "A"; } stop = System.nanoTime(); return stop - start; } public static long stringConcat() { long start; long stop; // String(concat) String str3 = ""; start = System.nanoTime(); for (int i = 0; i < LOOP; i++) { str3 = str3.concat("A"); } stop = System.nanoTime(); return stop - start; } public static long stringBuffer() { long start; long stop; // StringBuffer StringBuffer buffer = new StringBuffer(); start = System.nanoTime(); for (int i = 0; i < LOOP; i++) { buffer.append("A"); } stop = System.nanoTime(); return stop - start; } public static long stringBuilder() { long start; long stop; // StringBuilder StringBuilder builder = new StringBuilder(); start = System.nanoTime(); for (int i = 0; i < LOOP; i++) { builder.append("A"); } stop = System.nanoTime(); return stop - start; } public static void benchmark() { System.out.println("String(+):" + stringPlus()); System.out.println("String(+=):" + stringPlusEqual()); System.out.println("String(concat):" + stringConcat()); System.out.println("StringBuffer:" + stringBuffer()); System.out.println("StringBuilder:" + stringBuilder()); } public static void main(String[] args){ for (int i = 1; i <= 10; i++) { System.out.println(i + "セット目"); benchmark(); } } }
StringBufferとStringBuilderの違い
【StringBuffer】
導入JDK1.0 可変文字列を扱うためのクラス スレッドセーフ
public synchronized StringBuffer append(String str) { super.append(str); return this; }
※synchronizedがついてる
【StringBuilder】
導入JDK1.5 可変文字列を扱うためのクラス スレッドセーフではない
public StringBuilder append(String str) { super.append(str); return this; }
※synchronizedがついてない
まとめ
単一のスレッドにおいては+
を使うよりStringBuilder
を使うのが望ましいと思われます。
ただし、単一の固定文字列を一度だけ追加するような場合、私は+
やconcat
を
使用しています。コードの見やすさ、シンプルさを重要視。
以上、String[文字列結合]のお話でした。