Java中String和StringBuffer有什么区别?
String是否有最大长度限制?
Java中String和StringBuffer有什么区别?
String是否有最大长度限制?
int
来表示字符数组中字符的长度。这是理论上的长度。 - Vivin PaliathString
是不可变的,即在创建时就不能改变。
StringBuffer
(或其非同步的表兄弟StringBuilder
)用于需要逐个构建字符串而不会在此过程中构造大量小String
的性能开销的情况。
两者的最大长度均为Integer.MAX_VALUE,因为它们在内部存储为数组,而Java数组只有一个int
用于其长度伪字段。
对于多次连接,StringBuffer
比String
的性能提高相当显著。如果运行以下测试代码,则会看到差异。在我古老的笔记本电脑上使用Java 6,我得到以下结果:
Concat with String took: 1781ms Concat with StringBuffer took: 0ms
public class Concat
{
public static String concatWithString()
{
String t = "Cat";
for (int i=0; i<10000; i++)
{
t = t + "Dog";
}
return t;
}
public static String concatWithStringBuffer()
{
StringBuffer sb = new StringBuffer("Cat");
for (int i=0; i<10000; i++)
{
sb.append("Dog");
}
return sb.toString();
}
public static void main(String[] args)
{
long start = System.currentTimeMillis();
concatWithString();
System.out.println("Concat with String took: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
concatWithStringBuffer();
System.out.println("Concat with StringBuffer took: " + (System.currentTimeMillis() - start) + "ms");
}
}
String StringBuffer
Immutable Mutable
String s=new String("karthik"); StringBuffer sb=new StringBuffer("karthik")
s.concat("reddy"); sb.append("reddy");
System.out.println(s); System.out.println(sb);
O/P:karthik O/P:karthikreddy
--->once we created a String object ---->once we created a StringBuffer object
we can't perform any changes in the existing we can perform any changes in the existing
object.If we are trying to perform any object.It is nothing but mutablity of
changes with those changes a new object of a StrongBuffer object
will be created.It is nothing but Immutability
of a String object
Use String--->If you require immutabilty
Use StringBuffer---->If you require mutable + threadsafety
Use StringBuilder--->If you require mutable + with out threadsafety
String s=new String("karthik");
--->here 2 objects will be created one is heap and the other is in stringconstantpool(scp) and s is always pointing to heap object
String s="karthik";
--->In this case only one object will be created in scp and s is always pointing to that object only
String s=new String("karthik");
这会创建两个对象吗? - Asif MushtaqString是一个不可变的类。这意味着一旦你实例化了一个字符串实例,例如:
String str1 = "hello";
内存中的对象无法更改。相反,您将需要创建一个新实例,复制旧字符串并追加任何其他内容,如以下示例:
String str1 = "hello";
str1 = str1 + " world!";
这里实际上发生的是我们并没有更新现有的str1对象...我们重新分配了新的内存空间,将"hello"数据复制并在末尾添加了" world!",然后将str1引用设置为指向这个新的内存空间。所以在底层看起来更像是这样的:
String str1 = "hello";
String str2 = str1 + " world!";
str1 = str2;
因此,如果频繁地进行这种“复制+在内存中移动东西”的过程,特别是递归地进行时,它会非常昂贵。
当您面临反复执行某些操作的情况时,请使用StringBuilder。它是可变的,并且可以将字符串附加到当前字符串的末尾,因为它由一个可增长的数组支持(不确定是否实际使用了该数据结构,可能是列表)。从API:
一个线程安全可变的字符序列。StringBuffer类似于String,但可以被修改。在任何时刻,它都包含一些特定的字符序列,但是通过某些方法调用,序列的长度和内容可以被更改。
通过在append操作后打印String/StringBuffer对象的哈希码,也可以证明每次都会重新创建一个新的String对象,而不是使用相同的String对象。
public class MutableImmutable {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("String is immutable");
String s = "test";
System.out.println(s+"::"+s.hashCode());
for (int i = 0; i < 10; i++) {
s += "tre";
System.out.println(s+"::"+s.hashCode());
}
System.out.println("String Buffer is mutable");
StringBuffer strBuf = new StringBuffer("test");
System.out.println(strBuf+"::"+strBuf.hashCode());
for (int i = 0; i < 10; i++) {
strBuf.append("tre");
System.out.println(strBuf+"::"+strBuf.hashCode());
}
}
}
String is immutable
test::3556498
testtre::-1422435371
testtretre::-1624680014
testtretretre::-855723339
testtretretretre::2071992018
testtretretretretre::-555654763
testtretretretretretre::-706970638
testtretretretretretretre::1157458037
testtretretretretretretretre::1835043090
testtretretretretretretretretre::1425065813
testtretretretretretretretretretre::-1615970766
String Buffer is mutable
test::28117098
testtre::28117098
testtretre::28117098
testtretretre::28117098
testtretretretre::28117098
testtretretretretre::28117098
testtretretretretretre::28117098
testtretretretretretretre::28117098
testtretretretretretretretre::28117098
testtretretretretretretretretre::28117098
testtretretretretretretretretretre::28117098
String str = new String ("Stanford ");
str += "Lost!!";
StringBuffer str = new StringBuffer ("Stanford ");
str.append("Lost!!");
0 new #7 <Class java.lang.String>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #12 <Method java.lang.String(java.lang.String)>
9 astore_1
10 new #8 <Class java.lang.StringBuffer>
13 dup
14 aload_1
15 invokestatic #23 <Method java.lang.String valueOf(java.lang.Object)>
18 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
21 ldc #1 <String "Lost!!">
23 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
26 invokevirtual #22 <Method java.lang.String toString()>
29 astore_1
String str = new String("Stanford ");
str += "Lost!!";
0 new #8 <Class java.lang.StringBuffer>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
9 astore_1
10 aload_1
11 ldc #1 <String "Lost!!">
13 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
16 pop
StringBuffer str = new StringBuffer("Stanford ");
str.append("Lost!!");
StringBuffer 用于将多个字符串创建为一个字符串,例如当您想要在循环中追加字符串的部分时。
如果只有一个线程访问 StringBuffer,则应该使用 StringBuilder 而不是 StringBuffer,因为 StringBuilder 不同步,因此更快。
据我所知,作为一种语言,Java 中没有字符串大小的上限,但 JVM 可能有上限。
StringBuffer
或者它年轻且更快的兄弟 StringBuilder
在需要进行大量字符串拼接时更受青睐。string += newString;
或者等价地
string = string + newString;
因为上述结构隐式地每次都会创建一个新的字符串,这将导致巨大的性能下降。在内部,StringBuffer
/ StringBuilder
最好与动态可扩展的 List<Character>
进行比较。