在Java中使用String.format而不是字符串连接是否更好?

在Java中使用String.format而不是字符串连接是否更好?,java,string,concatenation,string.format,printf,Java,String,Concatenation,String.format,Printf,在Java中使用String.format和字符串连接之间有明显的区别吗 我倾向于使用String.format,但偶尔会滑倒并使用串联。我在想是不是一个比另一个好 在我看来,String.format在“格式化”字符串方面给了你更多的力量;连接意味着您不必担心意外地添加了一个额外的%s或丢失了一个 String.format也较短 哪个更具可读性取决于你的大脑工作方式。我建议最好使用String.format()。主要原因是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)
哪一个更具可读性取决于你的大脑如何工作

你的答案就在那里

这是个人品味的问题

我想字符串连接稍微快一些,但这应该可以忽略不计。

String.format()
不仅仅是连接字符串。例如,可以使用
String.format()
在特定区域设置中显示数字

但是,如果您不关心本地化,则没有功能上的差异。
也许一个比另一个快,但在大多数情况下,它可以忽略不计。

我没有做任何具体的基准测试,但我认为连接可能更快。format()创建一个新的格式化程序,该格式化程序反过来创建一个新的StringBuilder(大小仅为16个字符)。这是一个相当大的开销,尤其是当您正在格式化一个较长的字符串并且StringBuilder必须不断调整大小时

但是,串联不太有用,而且更难阅读。和往常一样,值得在代码上做一个基准测试,看看哪个更好。在将资源包、区域设置等加载到内存中并对代码进行JIT处理后,服务器应用程序中的差异可能可以忽略不计

也许作为一种最佳实践,最好使用大小合适的StringBuilder(可附加)和区域设置创建自己的格式化程序,并在需要进行大量格式化时使用它。

关于性能:

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");
}
publicstaticvoidmain(字符串[]args)引发异常{
长启动=System.currentTimeMillis();
对于(int i=0;i<1000000;i++){
字符串s=“Hi”+i+“Hi to you”+i*2;
}
long end=System.currentTimeMillis();
System.out.println(“连接=“+((结束-开始))+“毫秒”);
start=System.currentTimeMillis();
对于(int i=0;i<1000000;i++){
String s=String.format(“你好%s;你好%s”,i,+i*2);
}
end=System.currentTimeMillis();
System.out.println(“Format=“+((结束-开始))+“毫秒”);
}
计时结果如下:

  • 串联=265毫秒
  • 格式=4141毫秒

因此,串接比String.format快得多。

上面的程序无法比较String串接和String.format

您也可以尝试在代码块中交换使用字符串的位置。如下所示的格式和连接

public static void main(String[] args) throws Exception {      
  long start = System.currentTimeMillis();

  for( int i=0;i<1000000; i++){
    String s = String.format( "Hi %s; Hi to you %s",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") ;
}
publicstaticvoidmain(字符串[]args)引发异常{
长启动=System.currentTimeMillis();

对于(int i=0;i而言,可能存在明显差异


String.format
非常复杂,下面使用正则表达式,所以不要养成在任何地方都使用它的习惯,而要在需要的地方使用它


StringBuilder
会快一个数量级(正如这里已经有人指出的)。

因为有关于性能的讨论,我想我会添加一个包含StringBuilder的比较。它实际上比concat更快,当然也比String.format选项更快

为了使这成为一种苹果对苹果的比较,我在循环中而不是在外部实例化了一个新的StringBuilder(这实际上比只实例化一个要快,很可能是因为在一个生成器的末尾为循环追加重新分配空间的开销)

String formatString=“你好%s;你好%s”;
长启动=System.currentTimeMillis();
对于(int i=0;i<1000000;i++){
String s=String.format(formatString,i,+i*2);
}
long end=System.currentTimeMillis();
log.info(“Format=“+((结束-开始))+“毫秒”);
start=System.currentTimeMillis();
对于(int i=0;i<1000000;i++){
字符串s=“Hi”+i+“Hi to you”+i*2;
}
end=System.currentTimeMillis();
log.info(“Concatenation=“+((结束-开始))+“毫秒”);
start=System.currentTimeMillis();
对于(int i=0;i<1000000;i++){
StringBuilder bldString=新StringBuilder(“Hi”);
追加(i)追加(“你好”).append(i*2);
}
end=System.currentTimeMillis();
log.info(“字符串生成器=“+((结束-开始))+“毫秒”);
  • 2012-01-11 16:30:46058信息[TestMain]-格式=1416毫秒
  • 2012-01-11 16:30:46190信息[TestMain]-连接=134毫秒
  • 2012-01-11 16:30:46313信息[TestMain]-字符串生成器=117毫秒

使用
.format
的一个问题是,您失去了静态类型安全性。您也可以使用
    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");
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");

  }
}
> 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
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
  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");
  }