我读过一本Java书,上面写着:
因为 a
String是不可变的,所以使用StringBuffer效率更高。
我知道String实例是不可变的。
我也明白这StringBuffer使得处理字符串比平常更有效。
但我无法解决的问题是将这两个概念联系起来,即String不可变有什么帮助StringBuffer?
谢谢 :)
我读过一本Java书,上面写着:
因为 a
String是不可变的,所以使用StringBuffer效率更高。
我知道String实例是不可变的。
我也明白这StringBuffer使得处理字符串比平常更有效。
但我无法解决的问题是将这两个概念联系起来,即String不可变有什么帮助StringBuffer?
谢谢 :)
因为字符串是不可变的,所以要操作字符串,例如连接字符串,您必须创建新的字符串对象,因为很明显,您无法更改现有字符串对象的状态。而使用 StringBuffer 或 StringBuilder,您可以创建一个对象并简单地更改其状态。例如,如果您在 for 循环中进行一些主要的字符串连接,则此对象创建可能会变得非常昂贵。
话虽如此,我在这里看到许多批评不涉及大规模连接的简单字符串连接的帖子,在这种情况下,使用 StringBuffer 或 StringBuilder 是过早和不必要的优化的一个例子。
另请注意,您应该优先使用 StringBuilder 而不是 StringBuffer ,除非您的应用程序需要在多个线程中访问该对象并且不介意由此产生的额外开销。
它的意思是,由于 String 是不可变的,因此最好使用 StringBuffer(或 StringBuilder)进行 String 操作,因为每次更改底层 String 时都不会创建新对象。
所有其他帖子肯定回答了这个问题。我要补充一点,您应该始终选择StringBuilderover StringBuffer。 StringBuffer具有内置的线程同步,这是您几乎永远不需要的大量锁定开销。 StringBuilder没有这个,因此速度更快。
事实上,即使你想要线程安全,这里有一些很好的理由不使用StringBuffer.
但是我想不通的是是什么连接了这两个概念,即String是不可变的如何帮助StringBuffer?
它没有。我认为您只是误解了您引用的句子。
“因为 String 是不可变的,所以使用 StringBuffer 效率更高。”
据说 StringBuffer 是一个相对更有效的选择(对于某些任务)。换句话说:“因为 String 是不可变的,所以使用 StringBuffer [比在某些任务中使用 String] 更有效。”。
这并不是说StringBuffer绝对值比 String 不是不可变的要快。当然,这不是我阅读引文的方式......而且它也不是一个真实的陈述。
用这个例子可以很容易地解释不可变的概念
String s1 = "Hello";
String s2 = "Hi";
String s3 = "Hello";
if (s1 == s2){ System.out.println("s1==s2");}
if (s1 == s3){ System.out.println("s1==s3");}
s1 = "Hi";
if (s1 == s2){ System.out.println("s1==s2");}
if (s1 == s3){ System.out.println("s1==s3");}
如果你执行这段代码,你会得到
s1==s3和s1==s2. 这个例子说明了什么?
当您创建 s1 时,编译器在其字符串表中创建了一个字符串“Hello”(我不记得它的确切名称)。当您创建 s2 时,它会创建新对象“Hi”。现在,当您创建 s3 时,编译器知道它的字符串表中已经有一个对象“Hello”,所以为什么不直接将 s3 引用到它。所以 s1=s3 (内存虎钳)。当您将值“hi”分配给 s1 时也会发生同样的情况,编译器可以看到“hi”已经在 s3 指向的内存中,因此它也将其指向 s1。
在 StringBuffer 的情况下,编译器将内存分配给对象,您可以像在 String 的情况下那样操作它而不是“池”。