您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Java代碼中字符串拼接方式有哪些”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Java代碼中字符串拼接方式有哪些”這篇文章吧。
系統: windows 10 21H1
JDK: OpenJDK 1.8.0_302
@Slf4j public class StringConcat { @SneakyThrows public static void main(String[] args) { log.info("java虛擬機預熱開始"); String[] strs = new String[6000000]; for (int i = 0; i < strs.length; i++) { strs[i] = id(); } loopStringJoiner(strs); loopStringJoin(strs); loopStringBuilder(strs); log.info("java虛擬機預熱結束"); Thread.sleep(1000); log.info("開始測試:"); Thread.sleep(1000); Stopwatch stopwatchLoopPlus = Stopwatch.createStarted(); // loopPlus(strs); log.info("loop-plus: " + stopwatchLoopPlus.elapsed(TimeUnit.MILLISECONDS)); Thread.sleep(1000); Stopwatch stopwatchLoopStringBuilderCapacity = Stopwatch.createStarted(); loopStringBuilderCapacity(strs); log.info("loop-stringBuilderCapacity: " + stopwatchLoopStringBuilderCapacity.elapsed(TimeUnit.MILLISECONDS)); Thread.sleep(1000); Stopwatch stopwatchLoopStringBuilder = Stopwatch.createStarted(); loopStringBuilder(strs); log.info("loop-stringBuilder: " + stopwatchLoopStringBuilder.elapsed(TimeUnit.MILLISECONDS)); Thread.sleep(1000); Stopwatch stopwatchLoopJoin = Stopwatch.createStarted(); loopStringJoin(strs); log.info("loop-String.join: " + stopwatchLoopJoin.elapsed(TimeUnit.MILLISECONDS)); Thread.sleep(1000); Stopwatch stopwatchLoopStringJoiner = Stopwatch.createStarted(); loopStringJoiner(strs); log.info("loop-stringJoiner: " + stopwatchLoopStringJoiner.elapsed(TimeUnit.MILLISECONDS)); Thread.sleep(1000); Stopwatch stopwatchSimplePlus = Stopwatch.createStarted(); for (int i = 0; i < 500000; i++) { simplePlus(id(), id(), id()); } log.info("simple-Plus: " + stopwatchSimplePlus.elapsed(TimeUnit.MILLISECONDS)); Thread.sleep(1000); Stopwatch stopwatchSimpleStringBuilder = Stopwatch.createStarted(); for (int i = 0; i < 500000; i++) { simpleStringBuilder(id(), id(), id()); } log.info("simple-StringBuilder: " + stopwatchSimpleStringBuilder.elapsed(TimeUnit.MILLISECONDS)); Thread.sleep(1000); Stopwatch stopwatchSimpleStringBuffer = Stopwatch.createStarted(); for (int i = 0; i < 500000; i++) { simpleStringBuffer(id(), id(), id()); } log.info("simple-StringBuffer: " + stopwatchSimpleStringBuffer.elapsed(TimeUnit.MILLISECONDS)); } private static String loopPlus(String[] strs) { String str = ""; for (String s : strs) { str = str + "+" + s; } return str; } private static String loopStringBuilder(String[] strs) { StringBuilder str = new StringBuilder(); for (String s : strs) { str.append("+"); str.append(s); } return str.toString(); } private static String loopStringBuilderCapacity(String[] strs) { StringBuilder str = new StringBuilder(strs[0].length() * strs.length); for (String s : strs) { str.append("+"); str.append(s); } return str.toString(); } private static String loopStringJoin(String[] strs) { StringJoiner joiner = new StringJoiner("+"); for (String str : strs) { joiner.add(str); } return joiner.toString(); } private static String loopStringJoiner(String[] strs) { return String.join("+", strs); } private static String simplePlus(String a, String b, String c) { return a + "+" + b + "+" + c; } private static String simpleStringBuilder(String a, String b, String c) { StringBuilder builder = new StringBuilder(); builder.append(a); builder.append("+"); builder.append(b); builder.append("+"); builder.append(c); return builder.toString(); } private static String simpleStringBuffer(String a, String b, String c) { StringBuffer buffer = new StringBuffer(); buffer.append(a); buffer.append("+"); buffer.append(b); buffer.append("+"); buffer.append(c); return buffer.toString(); } private static String id() { return UUID.randomUUID().toString(); } }
結果及總結
- java虛擬機預熱開始
- java虛擬機預熱結束
- 開始測試:
- loop-plus: 執行超時
- loop-stringBuilderCapacity: 285
- loop-stringBuilder: 1968
- loop-String.join: 1313
- loop-stringJoiner: 1238
- simple-Plus: 812
- simple-StringBuilder: 840
- simple-StringBuffer: 857
多次測試,可發現在字符串循環拼接場景下,直接使用“+”號性能最低,有初始容量的StringBuilder性能最高,其他方式性能均沒有太大差異。
多次測試,可發現在字符串簡單拼接場景下,使用“+”號、StringBuilder、StringBuffer性能差距在5%左右,可理解為測試誤差,可認為三種方式性能一致。
1. StringBuilder與StringBuffer對比
在無爭搶共享資源的場景下,JVM會使用偏向鎖等方法優化,甚至會進行鎖消除,使用Synchronized關鍵詞與否,性能并無明顯差異。
2. 字節碼分析
對比上述#simplePlus和#simpleStringBuilder兩個方法的字節碼,可明顯看到兩方法執行內容基本一致,但是直接使用"+"號時處理流程更短,可見編譯器進行了深度優化,使用優化后的字節碼理論上會有更高的性能:
// access flags 0xA private static simplePlus(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; // parameter a // parameter b // parameter c L0 LINENUMBER 125 L0 NEW java/lang/StringBuilder DUP INVOKESPECIAL java/lang/StringBuilder.<init> ()V ALOAD 0 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; LDC "+" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; ALOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; LDC "+" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; ALOAD 2 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String; ARETURN L1 LOCALVARIABLE a Ljava/lang/String; L0 L1 0 LOCALVARIABLE b Ljava/lang/String; L0 L1 1 LOCALVARIABLE c Ljava/lang/String; L0 L1 2 MAXSTACK = 2 MAXLOCALS = 3 // access flags 0xA private static simpleStringBuilder(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; // parameter a // parameter b // parameter c L0 LINENUMBER 129 L0 NEW java/lang/StringBuilder DUP INVOKESPECIAL java/lang/StringBuilder.<init> ()V ASTORE 3 L1 LINENUMBER 130 L1 ALOAD 3 ALOAD 0 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; POP L2 LINENUMBER 131 L2 ALOAD 3 LDC "+" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; POP L3 LINENUMBER 132 L3 ALOAD 3 ALOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; POP L4 LINENUMBER 133 L4 ALOAD 3 LDC "+" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; POP L5 LINENUMBER 134 L5 ALOAD 3 ALOAD 2 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; POP L6 LINENUMBER 135 L6 ALOAD 3 INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String; ARETURN L7 LOCALVARIABLE a Ljava/lang/String; L0 L7 0 LOCALVARIABLE b Ljava/lang/String; L0 L7 1 LOCALVARIABLE c Ljava/lang/String; L0 L7 2 LOCALVARIABLE builder Ljava/lang/StringBuilder; L1 L7 3 MAXSTACK = 2 MAXLOCALS = 4
以上是“Java代碼中字符串拼接方式有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。