使用String和使用String之间有明显的区别吗?格式和字符串连接在Java?
我倾向于使用String。格式,但偶尔会滑倒和使用连接。我想知道哪个比哪个好。
在我看来,String。Format让你在“格式化”字符串时更强大;连接意味着您不必担心不小心输入了额外的%s或遗漏了一个。
字符串。格式也更短。
哪一个更容易读,取决于你的大脑如何工作。
使用String和使用String之间有明显的区别吗?格式和字符串连接在Java?
我倾向于使用String。格式,但偶尔会滑倒和使用连接。我想知道哪个比哪个好。
在我看来,String。Format让你在“格式化”字符串时更强大;连接意味着您不必担心不小心输入了额外的%s或遗漏了一个。
字符串。格式也更短。
哪一个更容易读,取决于你的大脑如何工作。
当前回答
可能会有明显的差别。
字符串。Format相当复杂,在底层使用正则表达式,所以不要习惯在任何地方使用它,只在需要它的地方使用。
StringBuilder会快一个数量级(这里有人已经指出了)。
其他回答
错误的测试重复多次 不应该使用{}%s。
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
long end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format("Hi %s; Hi to you %s", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("Wrong use of the message format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format("Hi {0}; Hi to you {1}", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("Good use of the message format = " + ((end - start)) + " millisecond");
}
Concatenation = 88 millisecond
Wrong use of the message format = 1075 millisecond
Good use of the message format = 376 millisecond
一般来说,字符串连接应该优先于string .format。后者有两个主要缺点:
它不以本地方式对要构建的字符串进行编码。 构建过程编码在字符串中。
第一点,我的意思是不可能理解String.format()调用在一次连续传递中所做的事情。人们被迫在格式字符串和参数之间来回切换,同时计算参数的位置。对于短连接,这不是什么大问题。但是,在这些情况下,字符串连接不那么详细。
第2点,我的意思是构建过程的重要部分编码在格式字符串中(使用DSL)。使用字符串表示代码有很多缺点。它本身不是类型安全的,并且使语法高亮显示、代码分析和优化等变得复杂。
当然,在使用Java语言之外的工具或框架时,可能会出现新的因素。
我想我们可以用MessageFormat。格式,因为它应该在可读性和性能方面都很好。
我使用了与Icaro在上面的回答中使用的相同的程序,并通过添加使用MessageFormat来解释性能数字的代码来增强它。
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
long end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format("Hi %s; Hi to you %s", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = MessageFormat.format("Hi %s; Hi to you %s", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("MessageFormat = " + ((end - start)) + " millisecond");
}
串联= 69毫秒 格式= 1435毫秒 MessageFormat = 200毫秒
更新:
根据SonarLint报告,printf风格的格式字符串应该正确使用(squid:S3457)
Because printf-style format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that result in the wrong strings being created. This rule statically validates the correlation of printf-style format strings to their arguments when calling the format(...) methods of java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat, and java.io.PrintWriter classes and the printf(...) methods of java.io.PrintStream or java.io.PrintWriter classes.
我用括号替换了printf样式,得到了一些有趣的结果,如下所示。
串联= 69毫秒格式= 1107毫秒 格式:括号= 416毫秒MessageFormat = 215 毫秒MessageFormat:括号= 2517毫秒
我的结论是: 如上所述,使用String。带尖括号的格式应该是一个很好的选择,以获得良好的可读性和性能。
.format的一个问题是失去了静态类型安全性。格式的参数可能过少,格式说明符的类型也可能错误——这两种情况都会导致运行时出现IllegalFormatException异常,因此可能会生成破坏生产的日志代码。
相反,+的参数可以由编译器测试。
printf的安全历史(格式化函数是在它的基础上建模的)是漫长而可怕的。
哪一个更容易读,取决于你的大脑如何工作。
你已经得到答案了。
这是个人喜好的问题。
我认为,字符串连接稍微快一些,但这应该可以忽略不计。