在Java中构建字符串是否有“最快的方法”?

时间:2009-12-03 18:47:06

标签: java string

我通常用以下方式在Java中创建一个String:

String foo = "123456";

但是,我的讲师坚持要求我使用format方法形成一个字符串,如下所示:

String foo = String.format("%s", 123456);

快得多。

此外,他说使用StringBuilder类的速度更快。

StringBuilder sb = new StringBuilder();
String foo = sb.append(String.format("%s", 123456)).toString();


什么是创建字符串的最快方法,如果有一个

他们不能100%准确,因为我可能不会完全记住它们。

9 个答案:

答案 0 :(得分:25)

如果只有一个字符串,那么:

String foo = "123456";

最快。您会注意到String.format行中已声明"%s%",因此我看不出讲师如何认为这更快。另外,你还有一个方法调用。

但是,如果你正在构建一个字符串,例如在for循环中,那么你将需要使用StringBuilder。如果您只是使用+=,则每次调用+=行时,您都会构建一个全新的字符串。 StringBuilder更快,因为它每次调用append时都会保留一个缓冲区并附加到它。

答案 1 :(得分:14)

稍微偏离主题,但我希望整个“必须不使用 - 加上连接 - 串在Java中”的神话会消失。尽管在Java的早期版本中可能确实存在StringBuffer更快且“+是邪恶的”,但在现代JVM中处理大量优化的情况肯定不是这样。

例如哪个更快?

String s = "abc" + "def";

    StringBuffer buf = new StringBuffer();
    buf.append("abc");
    buf.append("def");
    String s = buf.toString();

答案是前者。 JVM认识到这是一个字符串常量,实际上将“abcdef”放在字符串池中,而“优化的字符串缓冲”版本将导致构建一个额外的StringBuffer对象。

另一个JVM优化是

String s = onestring + " concat " + anotherstring;

JVM将在哪里找出最好的连接方式。在JDK 5中,这意味着StringBuilder将在内部使用,并且比使用字符串缓冲区更快。

但正如其他答案所说,你问题中的“123456”常数肯定是最快的方式而你的讲师应该回到成为一名学生: - )

是的,我已经非常伤心,通过查看Java字节码来验证这一点......

答案 2 :(得分:11)

这整个讨论都没有实际意义。请阅读Jeff撰写的这篇文章,即创建Stack Overflow的人。

The Sad Tragedy of Micro-Optimization Theater

请将您的导师转介到这篇文章,并要求他停止用无用的信息毁掉他/她的学生的大脑。算法优化是代码生存或死亡的地方,而不是用于构造字符串的方法。在任何情况下,StringBuilder和String格式化程序都必须使用REAL MEMORY执行ACTUAL CODE,如果你只是构造一个字符串,它在编译期间被预留并准备好在你需要它时使用,实质上它有0运行 - 时间成本,而其他选项有实际成本,因为代码实际上需要执行。

答案 3 :(得分:8)

String foo = "some string literal";

肯定是制作String的最快方法。它嵌入在.class文件中,是一个简单的内存查找方法。

当你没有真正的格式时,使用String.format看起来很丑陋,可能会导致初级开发人员哭泣。

如果要修改字符串,那么StringBuilder是最好的Strings immutable

答案 4 :(得分:5)

在你的第二个例子中,使用:

String foo = String.format("%s", 123456);

不会给你买任何东西; 123456已经是一个常数值,为什么不指定foo =“123456”?对于常量字符串,没有更好的方法。

如果要在运行时从多个部分创建一个字符串,请使用StringBuffer或StringBuilder(前者是线程安全的)。

答案 5 :(得分:4)

如果您的字符串在编译时已知,那么最好使用文字:String foo = "123456";

如果你的字符串在编译时是未知的并且由较小字符串的聚合组成,StringBuilder通常是要走的路(但要小心线程安全!)。

使用String foo = String.format("%s", 123456); 可以减少.class的大小并使类加载速度更快一点,但那将是非常激进(极端)的内存调整^^。< / p>

答案 6 :(得分:3)

正如已经指出的,如果您只是构建一个没有连接的字符串,只需使用String。

为了将多个位连接成一个大字符串,StringBuffer比StringBuilder慢,但StringBuffer是同步的。如果您不需要同步,请使用StringBuilder。

答案 7 :(得分:2)

你是否100%确定导师没有谈论类似的事情:

String foo = "" + 123456;

我看到我的学生“一直”做那种事情(每个学期都会做一些事情)。他们这样做的原因是有些书向他们展示了如何这样做。懒惰的书作家摇头和拳头!

答案 8 :(得分:1)

你给出的第一个例子是最快和最简单的。使用它。

您在这些示例中添加的每段代码都会使其显着变慢且难以阅读。

我建议示例2比示例1慢至少10-100x,示例3比示例2慢约2x。

您的处理器是否为此断言提供了任何理由?

BTW:你的第一个例子根本没有构造一个String(这就是它最快的原因),它只是给你一个坐在String常量池中的String。