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


当前回答

In java, String is immutable. Being immutable we mean that once a String is created, we can not change its value. StringBuffer is mutable. Once a StringBuffer object is created, we just append the content to the value of object instead of creating a new object. StringBuilder is similar to StringBuffer but it is not thread-safe. Methods of StingBuilder are not synchronized but in comparison to other Strings, the Stringbuilder runs fastest. You can learn difference between String, StringBuilder and StringBuffer by implementing them.

其他回答

You use String when an immutable structure is appropriate; obtaining a new character sequence from a String may carry an unacceptable performance penalty, either in CPU time or memory (obtaining substrings is CPU efficient because the data is not copied, but this means a potentially much larger amount of data may remain allocated). You use StringBuilder when you need to create a mutable character sequence, usually to concatenate several character sequences together. You use StringBuffer in the same circumstances you would use StringBuilder, but when changes to the underlying string must be synchronized (because several threads are reading/modifyind the string buffer).

这里有一个例子。

可变性的区别:

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

线程安全的区别:

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

情况:

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

就我个人而言,我认为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
----------------------------------------------------------------------------------

下面是一个小代码片段,演示了如何在异步环境中破坏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可以解决问题。更多详细信息请点击这里