使用String和使用String之间有明显的区别吗?格式和字符串连接在Java?

我倾向于使用String。格式,但偶尔会滑倒和使用连接。我想知道哪个比哪个好。

在我看来,String。Format让你在“格式化”字符串时更强大;连接意味着您不必担心不小心输入了额外的%s或遗漏了一个。

字符串。格式也更短。

哪一个更容易读,取决于你的大脑如何工作。


当前回答

我建议使用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()可以更容易地使用从资源文件加载的文本进行本地化,而拼接如果不为每种语言生成带有不同代码的新可执行文件就无法进行本地化。

如果你打算让你的应用程序本地化,你也应该养成为你的格式标记指定参数位置的习惯:

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

我想我们可以用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。带尖括号的格式应该是一个很好的选择,以获得良好的可读性和性能。

你不能比较字符串连接和字符串。格式由上面的程序。

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

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

您会惊讶地发现,Format在这里工作得更快。这是因为创建的初始对象可能不会被释放,内存分配可能会出现问题,从而影响性能。

性能:

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

授时结果如下:

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

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

可能会有明显的差别。

字符串。Format相当复杂,在底层使用正则表达式,所以不要习惯在任何地方使用它,只在需要它的地方使用。

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