在Java中使用String或StringBuffer:哪个更好?

时间:2010-07-19 07:24:18

标签: java string

我阅读了很多关于使用StringBuffer和String的内容,特别是在Java中涉及串联以及是否是线程安全的情况下。

那么,在各种Java方法中应该使用哪些?

例如,在PreparedStatement中,查询应该是StringBuffer:

    String query = ("SELECT * " +
                    "FROM User " +
                    "WHERE userName = ?;");

    try {
        ps = connection.prepareStatement(query);

然后再次使用String实用程序方法:

public static String prefixApostrophesWithBackslash(String stringIn) {
    String stringOut = stringIn.replaceAll("'", "\\\\'");
    return stringOut;
}

 // Removes a char from a String.
public static String removeChar(String stringIn, char c) {
    String stringOut = ("");
    for (int i = 0; i < stringIn.length(); i++) {
        if (stringIn.charAt(i) != c) {
            stringOut += stringIn.charAt(i);
        }
    }
    return stringOut;
}

我应该使用StringBuffers吗?特别是当repalceAll无法用于此类物体时。

由于

摩根先生。

感谢您的所有建议。 StringBuffers已被StringBuilders取代,并且Stringings被StringBuilders取代,我认为它最好。

6 个答案:

答案 0 :(得分:7)

您几乎不需要使用StringBuffer

而不是StringBuffer你可能意味着StringBuilder。 StringBuffer类似于StringBuilder,除了它还提供线程安全性。在实践中很少需要这种线程安全性,只会导致代码运行得更慢。

您的问题似乎不是关于String vs StringBuffer,而是关于使用内置方法或自己实现代码。如果有一个内置方法完全符合您的要求,您应该使用它。它可能比您编写的代码更好地优化。

答案 1 :(得分:3)

没有简单的答案(除了重复StringBuilderStringBuffer的咒语......)。为了选择最有效的解决方案,你真的非常了解“引擎盖下”的内容。

在您的第一个示例中,String是可行的方法。对于由一系列String连接组成的任何表达式,Java编译器可以生成非常优化的代码(如果需要,使用StringBuilder)。并且,如果连接的字符串都是常量或文字,编译器实际上可以在编译时进行连接。

在您的第二个示例中,尚不完全清楚StringStringBuilder是否更好......或者它们是否大致相同。人们需要查看java.util.regex.Matcher类的代码来解决这个问题。

编辑 - 我查看了代码,实际上,使用String或StringBuilder作为源代码没什么区别。在内部,Matcher.replaceAll方法创建一个新的StringBuilder,并通过附加源String和替换字符串中的块来填充它。

在你的第三个例子中,StringBuilder显然是最好的。当前一代Java编译器无法优化代码(如编写的那样),以避免在添加每个字符时创建新的String。

答案 2 :(得分:1)

以下代码段

 // Removes a char from a String.
public static String removeChar(String stringIn, char c) {
    String stringOut = ("");
    for (int i = 0; i < stringIn.length(); i++) {
        if (stringIn.charAt(i) != c) {
            stringOut += stringIn.charAt(i);
        }
    }
    return stringOut;
}

您可以stringIn.replaceAll(c+"","")

答案 3 :(得分:1)

即使在MT代码中,多个线程将字符串附加到字符串也是不寻常的。 StringBuilder几乎总是首选StringBuffer。

答案 4 :(得分:1)

现代编译器已经优化了代码。所以一些String添加将被优化以使用StringBuilder,如果我们认为我们可以保留String添加,它会增加可读性。

示例1:

String query = ("SELECT * " +
                "FROM User " +
                "WHERE userName = ?;");

将优化为:

StringBuiler sb = new StringBuilder();
sb.append("SELECT * ");
sb.append("FROM User ");
sb.append("WHERE userName = ?;");
String query = sb.toString();

示例2:

String numbers = "";
for (int i = 0;i < 20; i++)
  numbers = numbers + i;

这无法优化,我们应该在代码中使用StringBuilder。


我为SUN jdk1.5 +做了这个观察。因此,对于较旧的Java版本或不同的jdks,它可能会有所不同。可以保存为始终编码StringBuilder(或jdk 1.4.2及更早版本的StringBuffer)。

答案 5 :(得分:0)

对于可被视为单线程的情况,最好的是StringBuilder。它不会添加任何同步开销,而StringBuffer会这样做。

'+'运算符的字符串连接只有在您懒惰使用StringBuilder或者只是希望保持代码易于阅读时才是“好的”,从性能的角度来看它是可接受的,例如在启动日志消息“LOG”中。 info(“正在启动实例”+“app_id +”of“+ app_name”;“