在Java中,我应该何时更喜欢String而不是StringBuilder?

时间:2015-06-24 08:59:49

标签: java hibernate jpa orm stringbuilder

我知道StringBuilder应优先于String,因为String将保存在常量字符串池中,并为其分配新值不会覆盖以前的值。但是,StringBuilder是一个覆盖其先前值的对象。

  • 在什么情况下我应该在StringBuilder上使用String,反之亦然。
  • 另外如果我在Hibernate的支持类中有String类型的变量,我应该使用StringBuilder吗?怎么样?

    ...
    Result result = (Result) criteria.list().get(0);
    
    
    class Result{
       String name;
       String fname;
       ...
    }
    

5 个答案:

答案 0 :(得分:2)

我将String用于修复的文本值。

在创建较大的文本字符串时使用StringBuilder:

final StringBuilder sb = new StringBuilder();
for(;;){
    sb.append("more text\n");//add text, StringBuilder's size will increase incrementally
    if(this.stop()){
         break;//stop loop
    }
}
final String result = sb.toString();// Create the final result to work with
System.out.println(result);//print result

对同步值使用StringBuffer而不是StringBuilder, 有关StringBuilder和StringBuffer之间的区别,请参阅https://stackoverflow.com/a/355092/928952

JavaDoc:StringBuffer(http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html):

  

线程安全,可变的字符序列。字符串缓冲区就像   一个字符串,但可以修改。在任何时间点它都包含一些   特定的字符序列,但长度和内容   序列可以通过某些方法调用来改变

JavaDoc:StringBuilder(http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html):

  

可变的字符序列。该类提供API   与StringBuffer兼容,但不保证   同步。此类旨在用作插入   在字符串缓冲区所在的位置替换StringBuffer   由单个线程使用(通常是这种情况)。哪里   可能,建议优先使用此类   StringBuffer,因为在大多数实现中它会更快。

JavaDoc:String(http://docs.oracle.com/javase/7/docs/api/java/lang/String.html):

  

String类表示字符串。中的所有字符串文字   Java程序,例如" abc",被实现为此实例   类。字符串是不变的;他们的价值观无法改变   被创造了。字符串缓冲区支持可变字符串。因为String   对象是不可变的,可以共享

基本上,您将String用于常量(不可变)的文本。

答案 1 :(得分:2)

一个简单的经验法则(String是一种表示字符串的类型.StringBuilder是一个可变字符流)

使用String表示文字值。根据定义,Java提供了字符串值的池,从而为您提供了一些空间优化。在文件批处理期间应用程序处理数百万个文本值的情况下,请考虑这一点。举个例子。

  String str1 = "Test";
  String str2 = "Test";

这里,str1 == str2(同一参考)

此外,+运算符在String中重载以构造来自不同类型的String。这可以在构造小字符串时使用(内部使用StringBuilder完成,所以不用担心) - 但不能在循环时使用。

仅在使用不同类型的小块构建目标字符串时使用StringBuilder(或旧版本StringBuffer) - 并且尤其是在循环内 - 这将有助于你要避免在字符串池中放置不必要的字符串片段。

   StringBuilder s1 = new StringBuilder("test");
   StringBuilder s2 = new StringBuilder("test");

这里,s1!= s2

另外,我不认为你可以操纵StringBuilder / Buffer的编码 - 同时String允许这样做。

编辑:代表Hibernate实体: 始终使用String表示班级中的文字类型。由于上述原因,这应该像肌肉记忆一样。例如,基本类型为intfloatchar等,文本类型为String。仅使用构建器来构建字符串,而不是表示类型,除非这是一个奇怪的要求。

答案 2 :(得分:2)

您应该使用String,因为String objects are cached in an object pool并且在您不做更改时可能会提供更好的效果。

StringBuilder仅在您继续连接String令牌时才有用,在规范化的数据库表格中不应该这样。

JVM会进行各种优化,即使您使用串联,JVM也可能会将该例程重写为StringBuilder版本。

同时阅读这个问题的答案:link

答案 3 :(得分:1)

当你必须对字符串进行大量修改时,应该使用java.lang.StringBuilder类。我们知道String对象是不可变的,所以如果你选择用String对象做很多操作,那么你将最终在String池中放弃许多被遗弃的String对象。 (即使在数十亿字节的RAM中,在丢弃的String池对象上浪费宝贵的内存也不是一个好主意。)另一方面,StringBuilder类型的对象可以反复修改而不会留下大量废弃的废弃物。字符串对象。

String x = "abc";
x.concat("def");
System.out.println("x = " + x); // output is "x = abc"


StringBuffer sb = new StringBuffer("abc");
sb.append("def");
System.out.println("sb = " + sb); // output is "sb = abcdef"

答案 4 :(得分:0)

String是不可变对象,一旦创建就无法更改。作为String创建的对象存储在常量字符串池中。 Java中的每个不可变对象都是线程安全的,这意味着String也是线程安全的。 字符串不能同时被两个线程使用。一旦分配了字符串就无法更改。

String  demo = "Test1" ;

上述对象存储在常量字符串池中,其值无法修改。

demo="Test2" ;

新的“Test2”字符串在常量池中创建,并由演示变量

引用

StringBuilder对象是可变的,我们可以对存储在对象中的值进行更改。这实际上意味着如果使用StringBuilder对象而不是String对象执行,诸如append之类的字符串操作会更有效。

StringBuilder demo2= new StringBuilder("Test1");

上述对象也存储在堆中,其值可以修改

demo2=new StringBuilder("Test1"); 

上面的语句是正确的,因为它修改了StringBuilder中允许的值。

所以你应该使用stringBuilder,你需要经常更新/修改字符串。