在我的应用程序中一切正常,但我想提高性能并优化我的代码。
这两个哪个更适合
1.初始化
String str1=new String("Hello");
String str2="Hello";
2.串联
System.out.println(s1 + s2);
System.out.println(new StringBuffer(S1).append(s2));
在我的应用程序中一切正常,但我想提高性能并优化我的代码。
这两个哪个更适合
1.初始化
String str1=new String("Hello");
String str2="Hello";
2.串联
System.out.println(s1 + s2);
System.out.println(new StringBuffer(S1).append(s2));
首先,不要提高性能和优化您的代码,除非您首先分析您的应用程序并意识到这样做的充分理由。
其次,对于 String 变量的初始化,最好不要使用 String 构造函数。使用常量字符串(如 str2 所做的那样),Java 可以将字符串对象从字符串池中拉出。
第三,不要使用 StringBuffer 进行连接。请改用 StringBuilder。StringBuffer 的方法是同步的,这会显着降低应用程序的速度。实际上,您的两种连接几乎相等,因为所有现代编译器都创建字节码,它使用 StringBuilder 来表示“s1 + s2”之类的表达式。
在初始化第二种方法很好,因为它只创建一个对象
字符串 str1=new String("你好");
这里创建了两个对象,一个在堆中,另一个在字符串池中
String str2="Hello";
这里只有一个对象在字符串池中被创建。
System.out.println(s1 + s2);
这里共有三个对象在字符串池中有 s1 s2 和 s1+s2
System.out.println(new StringBuffer(S1).append(s2));
这里头部区域只有一个对象,即S1+S2,所以在这两种情况下,第二种方法都很好
对于初始化,第二种方法更好:
String str2="Hello";
因为通过这种方式,您可以利用 Java 字符串池并避免不需要的分配。
对于连接,当您必须执行大量字符串连接时,第二种方法将是最好的选择,仅连接两个字符串,第一种方法更简单且足够......
采用
String str2="Hello";
用于字符串初始化,因为如果“Hello”字符串在 JVM 字符串池中可用,则不会创建新的内存对象
另外两个建议:
StringBuffer
它,因为它不会像String
类那样在每个字符串操作中创建新字符串。StringBuilder
StringBuffer 来避免不必要的开销,它是为多线程操作而设计的。对于初始化,最好使用第二个版本,因为这将启用 JVM 字符串“interned”,这意味着每次使用该常量时它总是可以返回相同的字符串实例。当遇到此代码时,第一个版本将始终创建一个新的 String 对象,从而产生额外的内存消耗。
对于连接,在像您的示例这样的简单情况下,编译器将进行优化,因此两种方式最终将基本相同。对于更复杂的字符串连接,最好使用 Stringbuffer 或 StringBuilder。当从多个线程访问 StringBuilder 时,必须使用 StringBuffer,在其他情况下,StringBuilder 将提供更好的性能,因为它不会进行任何锁定。
System.out.println(s1 + s2);
System.out.println(new StringBuffer(S1).append(s2));
从上面这两个来看,第一个会更快,因为+
被翻译成StringBuilder,比StringBuffer更快
无论如何......最快,但有些讨厌,添加2个字符串的方法是使用string1.concat(string2)
方法,不需要产生Buffer的Stringbuilder的新对象。
您还可以重用相同的 StringBuilder 来添加许多字符串,方法是sb.setLength(0)
在每个完全添加的字符串之后重置它
:
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);
在initialization
String str2="Hello";
是更好的方法
在concatenation
System.out.println(s1 + s2);
是更好的方法。
因为他们都使用String Constant pool
这是为了提高性能
1)Go for literals,字符串文字存储在一个公共池中。这有助于为具有相同内容的字符串共享存储空间以节省存储空间。通过 new 运算符分配的字符串对象存储在堆中,相同内容不共享存储。
以外
文字比使用构造函数更易于阅读。
2) 使用StringBuilder
而不是 + 来避免创建多个字符串对象。
对于第二点,有 2 到 3 个附加或 +,没有太大区别。但是当您将 50 个字符串相互附加时,这很重要。
可能有帮助:
大多数与内存相关的问题都由 java 本身维护/解决。我相信干净和可读的代码,除非它显示出重大影响。
在你真正需要它之前不要优化。
如果在不需要时进行优化,则会降低可读性并浪费时间。字符串初始化会给您带来性能问题的情况非常罕见。