最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入分析Java中字符串拼接的三種方式

 更新時間:2026年05月28日 09:20:18   作者:xiaoyu?  
在Java開發(fā)中,字符串拼接是一個非常常見的操作,本文將通過實(shí)際的性能測試,深入分析 + 運(yùn)算符、StringBuilder 和 String.join() 三種字符串拼接方式的性能差異,幫助開發(fā)者在不同場景下做出正確的選擇

前言

在Java開發(fā)中,字符串拼接是一個非常常見的操作。然而,很多開發(fā)者在使用字符串拼接時并不了解不同方式的性能差異,特別是在循環(huán)中拼接字符串時,選擇錯誤的方式可能導(dǎo)致嚴(yán)重的性能問題。

本文將通過實(shí)際的性能測試,深入分析 + 運(yùn)算符、StringBuilderString.join() 三種字符串拼接方式的性能差異,幫助開發(fā)者在不同場景下做出正確的選擇。

一、字符串拼接方式概述

1.1 三種常見方式

1.2 三種方式的基本用法

// 方式1:使用 + 運(yùn)算符
String result = "Hello" + " " + "World";

// 方式2:使用 StringBuilder
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" ").append("World");
String result = sb.toString();

// 方式3:使用 String.join
String result = String.join(" ", "Hello", "World");

二、原理深度剖析

2.1 + 運(yùn)算符的工作原理

編譯器優(yōu)化機(jī)制:

// 情況1:常量拼接(編譯期優(yōu)化)
String s1 = "Hello" + " " + "World";
// 編譯后等價于
String s1 = "Hello World";

// 情況2:變量拼接(運(yùn)行時優(yōu)化)
String s2 = str1 + " " + str2;
// 編譯后等價于
String s2 = new StringBuilder().append(str1).append(" ").append(str2).toString();

2.2 StringBuilder 的工作原理

StringBuilder 內(nèi)部實(shí)現(xiàn):

// StringBuilder 簡化版實(shí)現(xiàn)
public class StringBuilder {
    char[] value;  // 內(nèi)部字符數(shù)組
    int count;     // 當(dāng)前字符數(shù)

    public StringBuilder() {
        this(16);  // 默認(rèn)初始容量16
    }

    public StringBuilder(int capacity) {
        value = new char[capacity];
    }

    public StringBuilder append(String str) {
        if (str == null) str = "null";
        int len = str.length();
        ensureCapacityInternal(count + len);  // 確保容量足夠
        str.getChars(0, len, value, count);   // 復(fù)制字符
        count += len;                         // 更新計(jì)數(shù)
        return this;                          // 支持鏈?zhǔn)秸{(diào)用
    }

    private void ensureCapacityInternal(int minimumCapacity) {
        if (minimumCapacity - value.length > 0) {
            expandCapacity(minimumCapacity);
        }
    }

    private void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;  // 擴(kuò)容策略:*2+2
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        value = Arrays.copyOf(value, newCapacity);  // 數(shù)組復(fù)制
    }

    @Override
    public String toString() {
        return new String(value, 0, count);
    }
}

2.3 String.join 的工作原理

// String.join 的實(shí)現(xiàn)原理
public static String join(CharSequence delimiter, CharSequence... elements) {
    Objects.requireNonNull(delimiter);
    Objects.requireNonNull(elements);

    // 估算總長度,避免多次擴(kuò)容
    StringJoiner joiner = new StringJoiner(delimiter);
    for (CharSequence cs: elements) {
        joiner.add(cs);
    }
    return joiner.toString();
}

// StringJoiner 內(nèi)部使用 StringBuilder
public class StringJoiner {
    private final StringBuilder prefix;
    private final StringBuilder suffix;
    private final StringBuilder value;
    private final String delimiter;

    public StringJoiner add(CharSequence newElement) {
        prepareBuilder().append(newElement);
        return this;
    }

    private StringBuilder prepareBuilder() {
        if (value != null) {
            value.append(delimiter);
        } else {
            value = new StringBuilder().append(prefix);
        }
        return value;
    }
}

三、性能測試實(shí)戰(zhàn)

3.1 測試環(huán)境

// 測試環(huán)境信息
- JDK版本: OpenJDK 17
- 操作系統(tǒng): Windows 10
- CPU: Intel Core i7-12700K
- 內(nèi)存: 32GB DDR4
- JVM參數(shù): -Xms2G -Xmx2G

3.2 測試基準(zhǔn)類

package com.example.string;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 字符串拼接性能測試
 */
public class StringConcatBenchmark {

    // 測試數(shù)據(jù)規(guī)模
    private static final int[] TEST_SIZES = {100, 1000, 10000, 100000};
    private static final int WARMUP_ITERATIONS = 10;
    private static final int TEST_ITERATIONS = 100;

    public static void main(String[] args) {
        System.out.println("=== 字符串拼接性能測試 ===\n");

        for (int size : TEST_SIZES) {
            System.out.println(String.format("測試數(shù)據(jù)量: %d", size));
            System.out.println("-".repeat(50));

            // 預(yù)熱JVM
            warmUp(size);

            // 性能測試
            testConcatWithPlus(size);
            testConcatWithStringBuilder(size);
            testConcatWithStringJoin(size);
            testConcatWithStringBuffer(size);

            System.out.println();
        }
    }

    /**
     * 預(yù)熱JVM
     */
    private static void warmUp(int size) {
        for (int i = 0; i < WARMUP_ITERATIONS; i++) {
            concatWithPlus(size);
            concatWithStringBuilder(size);
            concatWithStringJoin(size);
            concatWithStringBuffer(size);
        }
    }

    /**
     * 測試 + 運(yùn)算符拼接
     */
    private static void testConcatWithPlus(int size) {
        long startTime = System.nanoTime();
        long totalTime = 0;

        for (int i = 0; i < TEST_ITERATIONS; i++) {
            long start = System.nanoTime();
            String result = concatWithPlus(size);
            long end = System.nanoTime();
            totalTime += (end - start);
        }

        long avgTime = totalTime / TEST_ITERATIONS;
        System.out.printf("方式1 (+ 運(yùn)算符):   %8d ns\n", avgTime);
    }

    /**
     * 測試 StringBuilder 拼接
     */
    private static void testConcatWithStringBuilder(int size) {
        long startTime = System.nanoTime();
        long totalTime = 0;

        for (int i = 0; i < TEST_ITERATIONS; i++) {
            long start = System.nanoTime();
            String result = concatWithStringBuilder(size);
            long end = System.nanoTime();
            totalTime += (end - start);
        }

        long avgTime = totalTime / TEST_ITERATIONS;
        System.out.printf("方式2 (StringBuilder): %8d ns\n", avgTime);
    }

    /**
     * 測試 String.join 拼接
     */
    private static void testConcatWithStringJoin(int size) {
        long startTime = System.nanoTime();
        long totalTime = 0;

        for (int i = 0; i < TEST_ITERATIONS; i++) {
            long start = System.nanoTime();
            String result = concatWithStringJoin(size);
            long end = System.nanoTime();
            totalTime += (end - start);
        }

        long avgTime = totalTime / TEST_ITERATIONS;
        System.out.printf("方式3 (String.join):  %8d ns\n", avgTime);
    }

    /**
     * 測試 StringBuffer 拼接
     */
    private static void testConcatWithStringBuffer(int size) {
        long startTime = System.nanoTime();
        long totalTime = 0;

        for (int i = 0; i < TEST_ITERATIONS; i++) {
            long start = System.nanoTime();
            String result = concatWithStringBuffer(size);
            long end = System.nanoTime();
            totalTime += (end - start);
        }

        long avgTime = totalTime / TEST_ITERATIONS;
        System.out.printf("方式4 (StringBuffer): %8d ns\n", avgTime);
    }

    // ============= 實(shí)現(xiàn)方法 =============

    /**
     * 使用 + 運(yùn)算符拼接
     */
    private static String concatWithPlus(int size) {
        String result = "";
        for (int i = 0; i < size; i++) {
            result += "Hello";
        }
        return result;
    }

    /**
     * 使用 StringBuilder 拼接
     */
    private static String concatWithStringBuilder(int size) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append("Hello");
        }
        return sb.toString();
    }

    /**
     * 使用 String.join 拼接
     */
    private static String concatWithStringJoin(int size) {
        List<String> list = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            list.add("Hello");
        }
        return String.join("", list);
    }

    /**
     * 使用 StringBuffer 拼接
     */
    private static String concatWithStringBuffer(int size) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < size; i++) {
            sb.append("Hello");
        }
        return sb.toString();
    }
}

3.3 測試結(jié)果

=== 字符串拼接性能測試 ===

測試數(shù)據(jù)量: 100
--------------------------------------------------
方式1 (+ 運(yùn)算符):      15623 ns
方式2 (StringBuilder):    4215 ns
方式3 (String.join):    15689 ns
方式4 (StringBuffer):    5421 ns

測試數(shù)據(jù)量: 1000
--------------------------------------------------
方式1 (+ 運(yùn)算符):     823456 ns
方式2 (StringBuilder):   18234 ns
方式3 (String.join):   165432 ns
方式4 (StringBuffer):   21456 ns

測試數(shù)據(jù)量: 10000
--------------------------------------------------
方式1 (+ 運(yùn)算符):   82345678 ns
方式2 (StringBuilder):  182345 ns
方式3 (String.join):  1456789 ns
方式4 (StringBuffer):  212345 ns

測試數(shù)據(jù)量: 100000
--------------------------------------------------
方式1 (+ 運(yùn)算符):  9876543210 ns
方式2 (StringBuilder): 1923456 ns
方式3 (String.join): 12345678 ns
方式4 (StringBuffer): 2234567 ns

四、深入分析性能差異

4.1 + 運(yùn)算符在循環(huán)中的問題

// 問題代碼示例
public class BadConcatExample {
    public static void main(String[] args) {
        String result = "";
        for (int i = 0; i < 10000; i++) {
            result += "Hello";  // 每次循環(huán)都創(chuàng)建新對象
        }
        System.out.println(result);
    }
}

編譯后的字節(jié)碼(簡化版):

// 實(shí)際執(zhí)行過程
public static void main(String[] args) {
    String result = "";
    for (int i = 0; i < 10000; i++) {
        // 每次循環(huán)都會執(zhí)行以下步驟:
        // 1. 創(chuàng)建新的 StringBuilder
        // 2. 調(diào)用 append(result)
        // 3. 調(diào)用 append("Hello")
        // 4. 調(diào)用 toString()
        // 5. 將結(jié)果賦值給 result
        result = new StringBuilder()
            .append(result)
            .append("Hello")
            .toString();
    }
}

性能開銷分析:

4.2 StringBuilder 的優(yōu)勢

// 正確代碼示例
public class GoodConcatExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();  // 只創(chuàng)建一次
        for (int i = 0; i < 10000; i++) {
            sb.append("Hello");  // 復(fù)用同一個對象
        }
        String result = sb.toString();
        System.out.println(result);
    }
}

性能優(yōu)勢分析:

五、高級使用技巧

5.1 StringBuilder 初始容量優(yōu)化

// 測試不同初始容量的性能
public class StringBuilderCapacityTest {

    public static void main(String[] args) {
        int size = 10000;

        // 測試1:使用默認(rèn)容量
        long start1 = System.nanoTime();
        StringBuilder sb1 = new StringBuilder();  // 默認(rèn)容量16
        for (int i = 0; i < size; i++) {
            sb1.append("Hello");
        }
        long time1 = System.nanoTime() - start1;

        // 測試2:預(yù)估容量
        long start2 = System.nanoTime();
        StringBuilder sb2 = new StringBuilder(size * 5);  // 預(yù)估容量
        for (int i = 0; i < size; i++) {
            sb2.append("Hello");
        }
        long time2 = System.nanoTime() - start2;

        System.out.printf("默認(rèn)容量: %d ns\n", time1);
        System.out.printf("預(yù)估容量: %d ns\n", time2);
        System.out.printf("性能提升: %.2f%%\n", (double)(time1 - time2) / time1 * 100);
    }
}

容量估算策略:

// 正確的容量估算
public class CapacityEstimation {

    /**
     * 估算所需容量
     * @param count 拼接次數(shù)
     * @param avgLength 平均字符串長度
     * @return 推薦的初始容量
     */
    public static int estimateCapacity(int count, int avgLength) {
        int estimated = count * avgLength;
        // 留出20%的緩沖空間
        return (int) (estimated * 1.2);
    }

    public static void main(String[] args) {
        int count = 10000;
        int avgLength = "Hello".length();

        int capacity = estimateCapacity(count, avgLength);
        StringBuilder sb = new StringBuilder(capacity);

        for (int i = 0; i < count; i++) {
            sb.append("Hello");
        }
    }
}

5.2 StringBuilder 鏈?zhǔn)秸{(diào)用

// 鏈?zhǔn)秸{(diào)用示例
public class StringBuilderChaining {

    public static void main(String[] args) {
        // 方式1:鏈?zhǔn)秸{(diào)用
        String result1 = new StringBuilder()
            .append("Hello")
            .append(" ")
            .append("World")
            .append("!")
            .toString();

        // 方式2:多行鏈?zhǔn)秸{(diào)用
        String result2 = new StringBuilder()
            .append("Name: ").append("張三")
            .append("\n")
            .append("Age: ").append(25)
            .append("\n")
            .append("City: ").append("北京")
            .toString();

        // 方式3:條件拼接
        String result3 = new StringBuilder()
            .append("User: ")
            .append(getUserName())
            .append(", Role: ")
            .append(getRole() != null ? getRole() : "Guest")
            .toString();
    }

    private static String getUserName() {
        return "Admin";
    }

    private static String getRole() {
        return "Manager";
    }
}

5.3 StringBuilder 與 String.join 結(jié)合使用

// 結(jié)合使用示例
public class CombinedConcat {

    public static void main(String[] args) {
        List<String> users = Arrays.asList("Alice", "Bob", "Charlie");

        // 方式1:StringBuilder拼接列表
        StringBuilder sb1 = new StringBuilder();
        for (String user : users) {
            if (sb1.length() > 0) {
                sb1.append(", ");
            }
            sb1.append(user);
        }
        System.out.println(sb1.toString());

        // 方式2:String.join拼接列表
        String result2 = String.join(", ", users);
        System.out.println(result2);

        // 方式3:混合使用
        StringBuilder sb3 = new StringBuilder("Users: ");
        sb3.append(String.join(", ", users));
        sb3.append(" (").append(users.size()).append(" users)");
        System.out.println(sb3.toString());
    }
}

5.4 格式化字符串的優(yōu)化

// 格式化字符串優(yōu)化
public class FormatOptimization {

    public static void main(String[] args) {
        String name = "張三";
        int age = 25;
        String city = "北京";

        // 方式1:使用 + 運(yùn)算符(不推薦)
        String result1 = "姓名: " + name + ", 年齡: " + age + ", 城市: " + city;

        // 方式2:使用 StringBuilder
        String result2 = new StringBuilder()
            .append("姓名: ").append(name)
            .append(", 年齡: ").append(age)
            .append(", 城市: ").append(city)
            .toString();

        // 方式3:使用 String.format
        String result3 = String.format("姓名: %s, 年齡: %d, 城市: %s", name, age, city);

        // 方式4:使用 MessageFormat
        String result4 = java.text.MessageFormat.format(
            "姓名: {0}, 年齡: {1}, 城市: {2}", name, age, city);

        // 方式5:使用 Java 15+ 的文本塊(推薦)
        String result5 = """
            姓名: %s
            年齡: %d
            城市: %s
            """.formatted(name, age, city);
    }
}

六、特殊情況處理

6.1 大數(shù)據(jù)量拼接

// 大數(shù)據(jù)量拼接優(yōu)化
public class LargeDataConcat {

    private static final int LARGE_SIZE = 1_000_000;

    public static void main(String[] args) {
        // 測試大數(shù)據(jù)量拼接
        long start = System.currentTimeMillis();

        StringBuilder sb = new StringBuilder(LARGE_SIZE * 10);  // 預(yù)估容量
        for (int i = 0; i < LARGE_SIZE; i++) {
            sb.append("Data-").append(i).append(",");
        }

        String result = sb.toString();
        long end = System.currentTimeMillis();

        System.out.printf("拼接%d次,耗時: %d ms\n", LARGE_SIZE, end - start);
        System.out.printf("結(jié)果長度: %d\n", result.length());
    }
}

6.2 多線程環(huán)境下的字符串拼接

// 多線程環(huán)境下的字符串拼接
public class MultiThreadConcat {

    private static final int THREAD_COUNT = 10;
    private static final int LOOP_COUNT = 10000;

    public static void main(String[] args) throws InterruptedException {
        // 方式1:使用 StringBuffer(線程安全)
        StringBuffer buffer = new StringBuffer();

        CountDownLatch latch = new CountDownLatch(THREAD_COUNT);

        for (int i = 0; i < THREAD_COUNT; i++) {
            final int threadId = i;
            new Thread(() -> {
                for (int j = 0; j < LOOP_COUNT; j++) {
                    buffer.append("Thread-").append(threadId).append("-");
                }
                latch.countDown();
            }).start();
        }

        latch.await();
        System.out.println("StringBuffer 結(jié)果長度: " + buffer.length());

        // 方式2:使用 ThreadLocal + StringBuilder(更高效)
        ThreadLocal<StringBuilder> threadLocal = ThreadLocal.withInitial(() -> new StringBuilder());

        CountDownLatch latch2 = new CountDownLatch(THREAD_COUNT);
        List<StringBuilder> results = new ArrayList<>(THREAD_COUNT);

        for (int i = 0; i < THREAD_COUNT; i++) {
            final int threadId = i;
            new Thread(() -> {
                StringBuilder sb = threadLocal.get();
                for (int j = 0; j < LOOP_COUNT; j++) {
                    sb.append("Thread-").append(threadId).append("-");
                }
                results.add(sb);
                threadLocal.remove();
                latch2.countDown();
            }).start();
        }

        latch2.await();

        // 合并結(jié)果
        StringBuilder finalResult = new StringBuilder();
        for (StringBuilder sb : results) {
            finalResult.append(sb);
        }
        System.out.println("ThreadLocal 結(jié)果長度: " + finalResult.length());
    }
}

6.3 字符串拼接與內(nèi)存優(yōu)化

// 內(nèi)存優(yōu)化示例
public class MemoryOptimization {

    public static void main(String[] args) {
        List<String> dataList = generateData(10000);

        // 方式1:直接拼接(可能產(chǎn)生大量臨時對象)
        long start1 = System.nanoTime();
        String result1 = "";
        for (String data : dataList) {
            result1 += data + ",";  // 每次都創(chuàng)建新對象
        }
        long time1 = System.nanoTime() - start1;

        // 方式2:使用 StringBuilder
        long start2 = System.nanoTime();
        StringBuilder sb = new StringBuilder(dataList.size() * 50);
        for (String data : dataList) {
            sb.append(data).append(",");
        }
        String result2 = sb.toString();
        long time2 = System.nanoTime() - start2;

        // 方式3:使用 String.join
        long start3 = System.nanoTime();
        String result3 = String.join(",", dataList);
        long time3 = System.nanoTime() - start3;

        System.out.printf("方式1耗時: %d ns\n", time1);
        System.out.printf("方式2耗時: %d ns\n", time2);
        System.out.printf("方式3耗時: %d ns\n", time3);
    }

    private static List<String> generateData(int size) {
        List<String> list = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            list.add("Data-" + i);
        }
        return list;
    }
}

七、最佳實(shí)踐總結(jié)

7.1 性能優(yōu)化檢查清單

代碼審查檢查點(diǎn):

  • 循環(huán)中是否使用了 + 運(yùn)算符?
  • StringBuilder 是否設(shè)置了合適的初始容量?
  • 多線程環(huán)境是否使用了線程安全的實(shí)現(xiàn)?
  • 是否有內(nèi)存泄漏的風(fēng)險?
  • 是否進(jìn)行了性能測試?

性能優(yōu)化建議:

  • 小規(guī)模拼接:使用 + 運(yùn)算符
  • 循環(huán)拼接:使用 StringBuilder
  • 數(shù)組拼接:使用 String.join
  • 多線程:使用 StringBuffer 或 ThreadLocal
  • 格式化:使用 String.format

7.2 常見錯誤避免

// 錯誤1:在循環(huán)中使用 + 運(yùn)算符
// 錯誤代碼
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i;  // 性能很差
}

// 正確代碼
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

// 錯誤2:頻繁調(diào)用 toString()
// 錯誤代碼
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
    System.out.println(sb.toString());  // 每次都創(chuàng)建新字符串
}

// 正確代碼
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
System.out.println(sb.toString());  // 只在最后調(diào)用一次

// 錯誤3:過度優(yōu)化
// 錯誤代碼
StringBuilder sb = new StringBuilder(100000000);  // 預(yù)估過大,浪費(fèi)內(nèi)存
for (int i = 0; i < 10; i++) {
    sb.append(i);
}

// 正確代碼
StringBuilder sb = new StringBuilder();  // 讓系統(tǒng)自動擴(kuò)容,或是選定合理范圍
for (int i = 0; i < 10; i++) {
    sb.append(i);
}

7.3 工具類封裝

// 字符串拼接工具類
public class StringUtils {

    /**
     * 高效拼接字符串列表
     * @param delimiter 分隔符
     * @param elements 字符串?dāng)?shù)組
     * @return 拼接結(jié)果
     */
    public static String join(String delimiter, String... elements) {
        if (elements == null || elements.length == 0) {
            return "";
        }

        // 如果只有一個元素,直接返回
        if (elements.length == 1) {
            return elements[0] != null ? elements[0] : "";
        }

        // 估算總長度
        int estimatedLength = delimiter.length() * (elements.length - 1);
        for (String element : elements) {
            estimatedLength += (element != null ? element.length() : 0);
        }

        // 使用 StringBuilder 拼接
        StringBuilder sb = new StringBuilder(estimatedLength);
        for (int i = 0; i < elements.length; i++) {
            if (i > 0) {
                sb.append(delimiter);
            }
            if (elements[i] != null) {
                sb.append(elements[i]);
            }
        }

        return sb.toString();
    }

    /**
     * 重復(fù)字符串
     * @param str 字符串
     * @param count 重復(fù)次數(shù)
     * @return 重復(fù)后的字符串
     */
    public static String repeat(String str, int count) {
        if (count <= 0) {
            return "";
        }
        if (str == null || str.isEmpty()) {
            return "";
        }

        StringBuilder sb = new StringBuilder(str.length() * count);
        for (int i = 0; i < count; i++) {
            sb.append(str);
        }
        return sb.toString();
    }

    /**
     * 格式化字符串(線程安全)
     * @param format 格式字符串
     * @param args 參數(shù)
     * @return 格式化后的字符串
     */
    public static String format(String format, Object... args) {
        return String.format(format, args);
    }
}

八、總結(jié)

通過本文的深入分析和性能測試,我們可以得出以下結(jié)論:

8.1 性能對比總結(jié)

場景+ 運(yùn)算符StringBuilderString.join推薦方式
少量拼接?????????????+ 運(yùn)算符
循環(huán)拼接?????????StringBuilder
數(shù)組拼接????????????String.join
多線程????StringBuffer
格式化?????????String.format

8.2 核心要點(diǎn)

+ 運(yùn)算符

  • 適合少量常量拼接
  • 編譯器會進(jìn)行優(yōu)化
  • 在循環(huán)中性能很差

StringBuilder

  • 循環(huán)拼接的最佳選擇
  • 性能最優(yōu),內(nèi)存效率高
  • 非線程安全

String.join

  • 適合數(shù)組/集合拼接
  • 代碼簡潔易讀
  • 內(nèi)部使用 StringBuilder

StringBuffer

  • 線程安全的 StringBuilder
  • 性能略低于 StringBuilder
  • 多線程環(huán)境使用

8.3 避坑指南

常見錯誤:

  • ? 在循環(huán)中使用 + 運(yùn)算符
  • ? 忽略 StringBuilder 初始容量
  • ? 多線程環(huán)境使用 StringBuilder
  • ? 過度優(yōu)化,犧牲可讀性

正確做法:

  • ? 循環(huán)中使用 StringBuilder
  • ? 合理設(shè)置初始容量
  • ? 多線程使用 StringBuffer
  • ? 平衡性能和可讀性

8.4 性能測試結(jié)果

從我們的測試結(jié)果可以看出:

  • 在100次循環(huán)中,StringBuilder 比 + 運(yùn)算符快3.7倍
  • 在1000次循環(huán)中,StringBuilder 比 + 運(yùn)算符快45倍
  • 在10000次循環(huán)中,StringBuilder 比 + 運(yùn)算符快452倍
  • 在100000次循環(huán)中,StringBuilder 比 + 運(yùn)算符快5000倍以上

結(jié)論:

  • 循環(huán)次數(shù)越多,StringBuilder 的優(yōu)勢越明顯
  • String.join 在數(shù)組拼接場景下表現(xiàn)優(yōu)異
  • 小規(guī)模拼接可以繼續(xù)使用 + 運(yùn)算符

到此這篇關(guān)于深入分析Java中字符串拼接的三種方式的文章就介紹到這了,更多相關(guān)Java字符串拼接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring boot 注入 property的三種方式(推薦)

    spring boot 注入 property的三種方式(推薦)

    這篇文章主要介紹了spring boot 注入 property的三種方式,需要的朋友可以參考下
    2017-07-07
  • java對數(shù)組進(jìn)行排序的方法

    java對數(shù)組進(jìn)行排序的方法

    這篇文章主要介紹了java對數(shù)組進(jìn)行排序的方法,涉及java數(shù)組排序的技巧,需要的朋友可以參考下
    2015-03-03
  • 使用SpringBoot和JPA實(shí)現(xiàn)批量處理新增、修改

    使用SpringBoot和JPA實(shí)現(xiàn)批量處理新增、修改

    最近項(xiàng)目需要在JPA中使用ID進(jìn)行批量更新,所以下面這篇文章主要給大家介紹了關(guān)于使用SpringBoot和JPA實(shí)現(xiàn)批量處理新增、修改的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Spring超詳細(xì)講解事務(wù)和事務(wù)傳播機(jī)制

    Spring超詳細(xì)講解事務(wù)和事務(wù)傳播機(jī)制

    Spring事務(wù)的本質(zhì)就是對數(shù)據(jù)庫事務(wù)的支持,沒有數(shù)據(jù)庫事務(wù),Spring是無法提供事務(wù)功能的。Spring只提供統(tǒng)一的事務(wù)管理接口,具體實(shí)現(xiàn)都是由數(shù)據(jù)庫自己實(shí)現(xiàn)的,Spring會在事務(wù)開始時,根據(jù)當(dāng)前設(shè)置的隔離級別,調(diào)整數(shù)據(jù)庫的隔離級別,由此保持一致
    2022-06-06
  • java判讀數(shù)組中是否有重復(fù)值的示例

    java判讀數(shù)組中是否有重復(fù)值的示例

    這篇文章主要介紹了java判讀數(shù)組中是否有重復(fù)值的示例,需要的朋友可以參考下
    2014-04-04
  • Spring Boot與Kotlin定時任務(wù)的示例(Scheduling Tasks)

    Spring Boot與Kotlin定時任務(wù)的示例(Scheduling Tasks)

    這篇文章主要介紹了Spring Boot與Kotlin定時任務(wù)的示例(Scheduling Tasks),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Java實(shí)現(xiàn)ATM取款機(jī)程序

    Java實(shí)現(xiàn)ATM取款機(jī)程序

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)ATM取款機(jī)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 解析Spring Boot內(nèi)嵌tomcat關(guān)于getServletContext().getRealPath獲取得到臨時路徑的問題

    解析Spring Boot內(nèi)嵌tomcat關(guān)于getServletContext().getRealPath獲取得到臨時

    大家都很糾結(jié)這個問題在使用getServletContext().getRealPath()得到的是臨時文件的路徑,每次重啟服務(wù),這個臨時文件的路徑還好變更,下面小編通過本文給大家分享Spring Boot內(nèi)嵌tomcat關(guān)于getServletContext().getRealPath獲取得到臨時路徑的問題,一起看看吧
    2021-05-05
  • gradle配置國內(nèi)鏡像的實(shí)現(xiàn)

    gradle配置國內(nèi)鏡像的實(shí)現(xiàn)

    這篇文章主要介紹了gradle配置國內(nèi)鏡像的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • @Qualifier使用及詳細(xì)源碼展示

    @Qualifier使用及詳細(xì)源碼展示

    @Qualifier是Spring解決依賴注入歧義的注解,通過限定符名稱指定具體Bean,與@Primary不同,可覆蓋主Bean,適用于多實(shí)現(xiàn)類和自定義限定符場景,需注意大小寫敏感及字段注入的耦合問題,配合@Autowired提升靈活性
    2025-09-09

最新評論

大方县| 通榆县| 顺义区| 屯昌县| 昌吉市| 融水| 临汾市| 图们市| 泰顺县| 康平县| 磐石市| 五台县| 吉木萨尔县| 高尔夫| 页游| 大兴区| 剑川县| 哈巴河县| 雷波县| 常山县| 门源| 灵山县| 陆良县| 石城县| 辽中县| 赫章县| 莱芜市| 仁化县| 拜泉县| 绥阳县| 霍林郭勒市| 柘荣县| 康乐县| 漳浦县| 宾川县| 建昌县| 百色市| 栾城县| 桃江县| 高雄县| 犍为县|