java中的字符串初始化和连接

时间:2013-09-10 09:15:11

标签: java performance

在我的应用程序中,一切正常,但我想提高性能并优化我的代码

这两个中哪一个更适合

1.initialisation

String str1=new String("Hello");
String str2="Hello";

2.concatenation

System.out.println(s1 + s2);
System.out.println(new StringBuffer(S1).append(s2));

9 个答案:

答案 0 :(得分:6)

首先,不要提高性能并优化代码,除非您首先分析了应用程序并实现了很好的理由。

其次,对于String变量的初始化,最好不要使用String构造函数。使用常量字符串(与str2一样),Java可以将String对象从字符串池中拉出来。

第三,不要使用StringBuffer进行连接。请改用StringBuilder。 StringBuffer的方法是同步的,这会显着降低应用程序的速度。实际上,你的两种连接几乎是相同的,因为所有现代编译器都创建了字节代码,它使用StringBuilder来表达“s1 + s2”这样的表达式。

答案 1 :(得分:1)

初始化中的

第二种方法很好,因为它只创建一个对象

  

String str1 = new String(“Hello”);

这里有两个对象在堆中创建,另一个在String pool

中创建
  

String str2="Hello";

此处只有一个对象在String池中创建。

  

System.out.println(s1 + s2);

这里共有三个对象,其中s1 s2和s1 + s2都在String pool

  

System.out.println(new StringBuffer(S1).append(s2));

这里头部区域只有一个物体 S1 + S2 所以在这两种情况下第二种方法都很好

答案 2 :(得分:1)

对于初始化,第二种方法更好:

String str2="Hello";

因为这样您可以使用Java String Pool并避免不需要的分配。

对于连接,当你必须执行大量的字符串连接时,第二种方法是最好的选择,只连接两个字符串,第一种方法更简单,更充分......

答案 3 :(得分:1)

使用

String str2="Hello";

用于字符串初始化,因为如果“Hello”字符串在JVM字符串池中是可用的,则不会创建新的内存对象

另外两个建议:

  1. 如果您正在操作字符串,请使用StringBuffer,因为它不会像String类那样创建每个字符串操作的新字符串。
  2. 如果你的应用程序是线程安全的,那么使用StringBuilder来避免不必要的StringBuffer开销,这是为多线程操作而设计的。

答案 4 :(得分:1)

对于初始化,最好使用第二个版本,因为这将使JVM成为字符串“interned”,这意味着每次使用该常量时它总是可以返回相同的String-instance。遇到此代码时,第一个版本将始终创建一个新的String对象,从而创建额外的内存消耗。

对于连接,在类似于您的示例的简单情况下,编译器将进行优化,因此两种方式最终都会基本相同。对于更复杂的String-concatenations,最好使用Stringbuffer或StringBuilder。从多个线程访问StringBuilder时,必须使用StringBuffer,在其他情况下,StringBuilder将提供更好的性能,因为它不会进行任何锁定。

答案 5 :(得分:1)

System.out.println(s1 + s2);
System.out.println(new StringBuffer(S1).append(s2));
  1. 从上述两个方面开始,首先会更快,因为+ is translated into StringBuilder, that is faster compared to StringBuffer

  2. 无论如何......最快,但有些讨厌的,添加2个字符串的方法是使用string1.concat(string2)方法,不需要生成Buffer的Stringbuilder的新对象。

  3. 您还可以重复使用相同的StringBuilder来添加多个字符串,方法是在每个完全添加的字符串后用sb.setLength(0)重置字符串

  4. StringBuilder sb = new StringBuilder();
    String done1 = sb.append("1").append("2").append("3").toString();
    sb.setLength(0);
    String done2 = sb.append("4").append("5").append("6").toString();
    sb.setLength(0);
    String done3 = sb.append("7").append("8").append("9").toString();
    sb.setLength(0);
    System.out.println(done1);
    System.out.println(done2);
    System.out.println(done3);
    

    最后,在内部循环中,你应该总是明确地使用StringBuilder / Buffer,忽略了使用+的魔力。因为你最终会得到许多临时的StringBuilder对象,而不是你应该在循环之前显式创建的对象。

        //not:
        String result = "";
        for (int i = 0; i < 20; i++) {
            result += i; // this would create new StringBuilding in bytecode
        }
        System.out.println(result);
    
        //but:
        StringBuilder result1 = new StringBuilder();
        for (int i = 0; i < 20; i++) {
            result1.append(i);
        }
        System.out.println(result1);
    

答案 6 :(得分:1)

initialization

 String str2="Hello";

是更好的方法

concatenation

System.out.println(s1 + s2);

是更好的方法。

因为他们使用String Constant pool来提高绩效

答案 7 :(得分:0)

1)Go for literals,String literals存储在公共池中。这有助于共享具有相同内容的字符串的存储空间以节省存储空间。通过new运算符分配的字符串对象存储在堆中,并且没有共享相同内容的存储空间。

除了

文字是读者友好的,而不是使用构造函数。

2)转到StringBuilder而不是+,避免多个字符串对象创建。

对于第二点,有2到3个附加或+,没有太大的区别。但是当你相互追加50个字符串时,这很重要。

可能有用:

大多数与内存相关的问题都是由java本身维护/解决的。我相信干净且可读的代码,除非它显示出重大影响。

答案 8 :(得分:0)

在您真正需要之前不要进行优化。

如果在不需要时进行优化,则会降低可读性和浪费时间。字符串初始化很少会导致性能问题。