在Java中使用String.format
和字符串拼接之间有明显的区别吗?
我倾向于使用String.format
,但偶尔会用拼接。我想知道哪一个更好。
我认为,String.format
在“格式化”字符串方面给您更多的控制权;而拼接意味着您不必担心意外地输入额外的%s或漏掉一个。
String.format
也更短。
哪个更易读取取决于您的思维方式。
在Java中使用String.format
和字符串拼接之间有明显的区别吗?
我倾向于使用String.format
,但偶尔会用拼接。我想知道哪一个更好。
我认为,String.format
在“格式化”字符串方面给您更多的控制权;而拼接意味着您不必担心意外地输入额外的%s或漏掉一个。
String.format
也更短。
哪个更易读取取决于您的思维方式。
我建议更好的做法是使用String.format()
。主要原因是String.format()
可以更容易地从资源文件加载文本进行本地化,而连接无法本地化,需要为每种语言生成不同代码的新可执行文件。
如果您计划将应用程序本地化,还应该养成指定格式标记的参数位置的习惯:
"Hello %1$s the time is %2$t"
这样就可以本地化,并且可以在无需重新编译可执行文件的情况下交换名称和时间标记,以适应不同的排序方式。使用参数位置时,还可以重复使用相同的参数,而无需将其两次传递到函数中:
String.format("Hello %1$s, your name is %1$s and the time is %2$t", name, time)
关于性能:
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("Format = " + ((end - start)) + " millisecond");
}
以下是时间结果:
因此,拼接比String.format快得多。
javap -c StringTest.class
,你会发现编译器会自动将“+”转换为StringBuilder,但仅限于不在循环中的情况。如果连接操作在单行完成,则与使用“+”相同,但如果你在多行上使用myString += "morechars";
或myString += anotherString;
,你会注意到可能创建了超过一个StringBuilder,因此使用“+”并不总是比StringBuilder更高效。 - ccpizza+
符号不会被转换为StringBuilder.append()
,而是在每次迭代时都会发生new StringBuilder()
。 - ccpizza鉴于关于性能的讨论,我觉得加入一个包括 StringBuilder 的比较会更好。实际上,StringBuilder 比 concat 和 String.format 更快。
为了进行一种类似苹果与苹果之间的比较,我在循环中创建了一个新的 StringBuilder 而不是在外部创建(这实际上比只创建一个 StringBuilder 更快,很可能是由于重新分配空间给循环末尾附加的开销造成的)。
String formatString = "Hi %s; Hi to you %s";
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format(formatString, i, +i * 2);
}
long end = System.currentTimeMillis();
log.info("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
end = System.currentTimeMillis();
log.info("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
StringBuilder bldString = new StringBuilder("Hi ");
bldString.append(i).append("; Hi to you ").append(i * 2);
}
end = System.currentTimeMillis();
log.info("String Builder = " + ((end - start)) + " millisecond");
bldString.toString()
来实现。希望这能解释清楚? - Jamey Sharp格式化 = 1520 毫秒
,拼接 = 167 毫秒
,字符串构建器 = 173 毫秒
我在一个循环中运行它们,并对每个进行平均以获得良好的重复性:(在 jvm 优化之前运行,将在有时间时尝试 10000+ 循环) 代码中的 String s = bldString.toString();
需要翻译。 - TechTrip哪个更易读取,这取决于你的思维方式。
你已经得到了答案。
这是个人口味的问题。
字符串连接稍微快一点,但应该可以忽略不计。
这是一个包含不同样本大小的以毫秒为单位的测试。
public class Time {
public static String sysFile = "/sys/class/camera/rear/rear_flash";
public static String cmdString = "echo %s > " + sysFile;
public static void main(String[] args) {
int i = 1;
for(int run=1; run <= 12; run++){
for(int test =1; test <= 2 ; test++){
System.out.println(
String.format("\nTEST: %s, RUN: %s, Iterations: %s",run,test,i));
test(run, i);
}
System.out.println("\n____________________________");
i = i*3;
}
}
public static void test(int run, int iterations){
long start = System.nanoTime();
for( int i=0;i<iterations; i++){
String s = "echo " + i + " > "+ sysFile;
}
long t = System.nanoTime() - start;
String r = String.format(" %-13s =%10d %s", "Concatenation",t,"nanosecond");
System.out.println(r) ;
start = System.nanoTime();
for( int i=0;i<iterations; i++){
String s = String.format(cmdString, i);
}
t = System.nanoTime() - start;
r = String.format(" %-13s =%10d %s", "Format",t,"nanosecond");
System.out.println(r);
start = System.nanoTime();
for( int i=0;i<iterations; i++){
StringBuilder b = new StringBuilder("echo ");
b.append(i).append(" > ").append(sysFile);
String s = b.toString();
}
t = System.nanoTime() - start;
r = String.format(" %-13s =%10d %s", "StringBuilder",t,"nanosecond");
System.out.println(r);
}
}
TEST: 1, RUN: 1, Iterations: 1
Concatenation = 14911 nanosecond
Format = 45026 nanosecond
StringBuilder = 3509 nanosecond
TEST: 1, RUN: 2, Iterations: 1
Concatenation = 3509 nanosecond
Format = 38594 nanosecond
StringBuilder = 3509 nanosecond
____________________________
TEST: 2, RUN: 1, Iterations: 3
Concatenation = 8479 nanosecond
Format = 94438 nanosecond
StringBuilder = 5263 nanosecond
TEST: 2, RUN: 2, Iterations: 3
Concatenation = 4970 nanosecond
Format = 92976 nanosecond
StringBuilder = 5848 nanosecond
____________________________
TEST: 3, RUN: 1, Iterations: 9
Concatenation = 11403 nanosecond
Format = 287115 nanosecond
StringBuilder = 14326 nanosecond
TEST: 3, RUN: 2, Iterations: 9
Concatenation = 12280 nanosecond
Format = 209051 nanosecond
StringBuilder = 11818 nanosecond
____________________________
TEST: 5, RUN: 1, Iterations: 81
Concatenation = 54383 nanosecond
Format = 1503113 nanosecond
StringBuilder = 40056 nanosecond
TEST: 5, RUN: 2, Iterations: 81
Concatenation = 44149 nanosecond
Format = 1264241 nanosecond
StringBuilder = 34208 nanosecond
____________________________
TEST: 6, RUN: 1, Iterations: 243
Concatenation = 76018 nanosecond
Format = 3210891 nanosecond
StringBuilder = 76603 nanosecond
TEST: 6, RUN: 2, Iterations: 243
Concatenation = 91222 nanosecond
Format = 2716773 nanosecond
StringBuilder = 73972 nanosecond
____________________________
TEST: 8, RUN: 1, Iterations: 2187
Concatenation = 527450 nanosecond
Format = 10291108 nanosecond
StringBuilder = 885027 nanosecond
TEST: 8, RUN: 2, Iterations: 2187
Concatenation = 526865 nanosecond
Format = 6294307 nanosecond
StringBuilder = 591773 nanosecond
____________________________
TEST: 10, RUN: 1, Iterations: 19683
Concatenation = 4592961 nanosecond
Format = 60114307 nanosecond
StringBuilder = 2129387 nanosecond
TEST: 10, RUN: 2, Iterations: 19683
Concatenation = 1850166 nanosecond
Format = 35940524 nanosecond
StringBuilder = 1885544 nanosecond
____________________________
TEST: 12, RUN: 1, Iterations: 177147
Concatenation = 26847286 nanosecond
Format = 126332877 nanosecond
StringBuilder = 17578914 nanosecond
TEST: 12, RUN: 2, Iterations: 177147
Concatenation = 24405056 nanosecond
Format = 129707207 nanosecond
StringBuilder = 12253840 nanosecond
这里与上文相同的测试,唯一的修改是在 StringBuilder 上调用了 toString() 方法。下面的结果表明,使用 + 操作符进行字符串连接的速度稍微快于 StringBuilder 方法。
文件: StringTest.java
class StringTest {
public static void main(String[] args) {
String formatString = "Hi %s; Hi to you %s";
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format(formatString, i, +i * 2);
}
long end = System.currentTimeMillis();
System.out.println("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
StringBuilder bldString = new StringBuilder("Hi ");
bldString.append(i).append("Hi to you ").append(i * 2).toString();
}
end = System.currentTimeMillis();
System.out.println("String Builder = " + ((end - start)) + " millisecond");
}
}
Shell命令:(编译并运行StringTest 5次)
> javac StringTest.java
> sh -c "for i in \$(seq 1 5); do echo \"Run \${i}\"; java StringTest; done"
结果:
Run 1
Format = 1290 millisecond
Concatenation = 115 millisecond
String Builder = 130 millisecond
Run 2
Format = 1265 millisecond
Concatenation = 114 millisecond
String Builder = 126 millisecond
Run 3
Format = 1303 millisecond
Concatenation = 114 millisecond
String Builder = 127 millisecond
Run 4
Format = 1297 millisecond
Concatenation = 114 millisecond
String Builder = 127 millisecond
Run 5
Format = 1270 millisecond
Concatenation = 114 millisecond
String Builder = 126 millisecond
String.format()
不仅仅是字符串拼接。例如,您可以使用String.format()
在特定语言环境下显示数字。
但是,如果您不关心本地化,那么没有功能上的区别。 也许拼接比其他方法更快,但在大多数情况下,这将是微不足道的。
String.format
。后者有两个主要缺点:
String.format()
调用正在执行什么操作。必须在格式化字符串和参数之间来回切换,同时计算参数的位置。对于短连接,这并不是什么问题。然而,在这些情况下,字符串连接更简洁。错误测试重复多次 您应该使用{}而不是%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