请告诉我一个实时情况比较字符串,StringBuffer,和StringBuilder?


当前回答

----------------------------------------------------------------------------------
                  String                    StringBuffer         StringBuilder
----------------------------------------------------------------------------------                 
Storage Area | Constant String Pool         Heap                   Heap 
Modifiable   |  No (immutable)              Yes( mutable )         Yes( mutable )
Thread Safe  |      Yes                     Yes                     No
 Performance |     Fast                 Very slow                  Fast
----------------------------------------------------------------------------------

其他回答

String和其他两个类的区别在于String是不可变的,而其他两个类是可变的。

但是为什么我们有两个相同目的的类呢?

原因是StringBuffer是线程安全的,而StringBuilder不是。 StringBuilder是StringBuffer Api上的一个新类,它是在JDK5中引入的,如果你工作在单线程环境中,总是推荐使用它,因为它要快得多

有关完整的详细信息,请访问http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/

可变性的区别:

String是不可变的,如果你试图改变它们的值,就会创建另一个对象,而StringBuffer和StringBuilder是可变的,所以它们可以改变它们的值。

线程安全的区别:

StringBuffer和StringBuilder的区别在于StringBuffer是线程安全的。因此,当应用程序只需要在一个线程中运行时,最好使用StringBuilder。StringBuilder比StringBuffer更有效。

情况:

如果你的字符串不会改变,请使用string类,因为string对象是不可变的。 如果您的字符串可以更改(例如:字符串构造中的大量逻辑和操作),并且只能从单个线程访问,那么使用StringBuilder就足够了。 如果您的字符串可以更改,并且可以从多个线程访问,请使用StringBuffer,因为StringBuffer是同步的,因此具有线程安全性。

下面是一个小代码片段,演示了如何在异步环境中破坏StringBuilder

public static void main(String[] args) throws InterruptedException {
    StringBuilder builder = new StringBuilder();

    ExecutorService executorService = Executors.newFixedThreadPool(50);
    for (int i = 0; i < 1000 * 1000; i++) {
        executorService.submit(new AppendRunnable(builder));
    }

    executorService.shutdown();
    executorService.awaitTermination(1, TimeUnit.MINUTES);

    Stream.of(builder.toString().split(System.lineSeparator()))
        .filter(line -> !line.equals("I just appended this!"))
        .forEach(System.out::println);
}

record AppendRunnable(StringBuilder stringBuilder) implements Runnable {

    @Override
    public void run() {
        stringBuilder.append("I just appended this!\n");
    }
}

本质上,我们将字符串附加到构建器中,并期望它们都等于“我刚刚附加了这个!”。但它们不是,其中一些前缀是空字符,因为构建器的内部字符缓冲区没有同步,它被错误地调整了大小。在这种情况下使用StringBuffer可以解决问题。更多详细信息请点击这里

----------------------------------------------------------------------------------
                  String                    StringBuffer         StringBuilder
----------------------------------------------------------------------------------                 
Storage Area | Constant String Pool         Heap                   Heap 
Modifiable   |  No (immutable)              Yes( mutable )         Yes( mutable )
Thread Safe  |      Yes                     Yes                     No
 Performance |     Fast                 Very slow                  Fast
----------------------------------------------------------------------------------

就我个人而言,我认为StringBuffer在现实世界中没有任何用处。什么时候我想通过操纵字符序列在多个线程之间进行通信?这听起来一点用都没有,但也许我还没有看到光明:)