29

基本的字符串连接操作应该使用什么?

String randomString = "hello " + userName + " how are you" ?

或者

String randomString = String.format("hello %s how are you ?",userName);

我觉得String.format()对输出字符串有更好的了解。但是使用其中任何一个实际上有什么优点和缺点

字符串文字池中是否有任何性能或孤儿条目。

编辑:我说的是字符串中的多个参数,而不仅仅是一个。5+左右。

奖金问题:还请分享您对实际应该使用哪一个的看法?这些或第三个中的任何一个......!?

4

9 回答 9

28

如果您只追求性能,我相信 usingStringBuilder/StringBuffer是构建字符串的最有效方式。即使 Java 编译器足够聪明,可以将大多数 String 连接转换为StringBuilder等价物。

如果您正在寻找可读性,String.format我认为事情会更清晰,这也是我使用的,除非我需要依赖高性能。

因此,如果您主要关心的不是性能,这意味着此代码不在一个被大量调用的路径中,您可能更喜欢使用String.format它,因为它可以更好地了解结果字符串(就像您说的那样)。

此外,usingString.format允许您使用 format 的东西,这意味着您可以使用它来填充字符串、格式化数字、日期等,如果使用简单的连接会使代码变得更糟。

为 Chuu编辑

使用JAD,您可以看到以下代码:

public class Test {
    public static void main(String[] args) {
        String str = "a" + "b" + "c";
        String str2 = "foo" + str + "bar" + str;
        System.out.println(str2);
    }
}

反编译后的样子:

public class Test {
    public static void main(String[] args) {
        String str = "abc";
        String str2 = new StringBuilder("foo").append(str).append("bar").append(str).toString();
        System.out.println(str2);
    }
}

也可以使用该javap实用程序来证明这一点,该实用程序将向您显示.class文件下的 Java 字节码:

public static void main(java.lang.String[] args);
    0  ldc <String "abc"> [16]
    2  astore_1 [str]
    3  new java.lang.StringBuilder [18]
    6  dup
    7  ldc <String "foo"> [20]
    9  invokespecial java.lang.StringBuilder(java.lang.String) [22]
   12  aload_1 [str]
   13  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   16  ldc <String "bar"> [29]
   18  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   21  aload_1 [str]
   22  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   25  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [31]
   28  astore_2 [str2]
   29  getstatic java.lang.System.out : java.io.PrintStream [35]
   32  aload_2 [str2]
   33  invokevirtual java.io.PrintStream.println(java.lang.String) : void [41]
   36  return
于 2012-12-11T07:24:05.833 回答
8

基本的字符串连接操作应该使用什么?

您提供的示例有不同的用途。+重载为 concat Strings,但String.format用于格式化字符串,如名称所指定。

将字符串连接在一起并不是主要工作。

因此,如果要求只是连接 use+concat方法。

这些链接将很有用:

如果性能很重要,我应该使用 Java 的 String.format() 吗?

在Java中使用String.format而不是字符串连接是更好的做法吗?

于 2012-12-11T07:21:25.793 回答
4

试试这个

    long t0 = System.currentTimeMillis();
        String userName = "test";
        for (int i = 0; i < 1000000; i++) {
            String randomString = "hello " + userName + " how are you?";
//          String randomString = String.format("hello %s how are you ?",userName);
        }
        System.out.println(System.currentTimeMillis() - t0);

你会惊讶地发现连接比 String.format 快 10 倍。但是 format 可以对数字、日期等做很多非常有用的事情。有关详细信息,请参阅 String.format 实际使用的 java.util.Formatter API。

于 2012-12-11T07:31:19.750 回答
2

我的两分钱:总是用String.format()

在这种情况下,国际化比风格或性能更受关注。出于这个原因,我会一直使用String.format()

英文文本:"Hello " + userName + " how are you?"

翻译成绝地:userName + "you are how? Hello!"

如果字符串是串联的,那么对于翻译者来说,即使不是不可能,也很难改变词序。这个问题变得越来越严重,因为字符串中有更多的片段和更多的占位符。

于 2012-12-11T08:26:47.327 回答
2

在我看来,使用+ operator.

如果性能是您应该使用的一个问题,StringBuilder并且正如 Alex 在上面的评论中指出的那样,Java 编译器将转换:

String str2 = "a" + str1;

到:String str2 = new StringBuilder("a").append(str1)).toString();

除此之外,您还可以使用+ operator. 相反,您会得到可以在编译时捕获的语法错误。例如:

    String var = "huge success.";

    System.out.print( "I'm making a note here: " + var );
    //System.out.print( "Printing: " + ); Syntax error!

    System.out.print( String.format( "I'm making a note here: '%s'", var ) );
    System.out.print( String.format( "I'm making a note here: '%s'" ) ); // runtime exception!
    System.out.print( String.format( "I'm making a note here: '%d'", var ) ); // runtime exception!

可读性归结为个人喜好。但是我会说String.format语法基本上来自 C++,并且从那时起创建的大多数语言都+ operator出于可读性的原因而接受了 C++。

于 2013-04-26T18:19:25.463 回答
1

就我个人而言,我更喜欢使用格式化,因为它看起来更好,而且我无法想象它会严重影响性能。

于 2012-12-11T07:23:57.910 回答
1

大多数推荐使用 StringBuffer 的人都生活在过去。当前的最佳实践是使用 StringBuilder。但这可能会改变,那么为什么不让编译器为你做呢?当您只使用“+”时,编译器将选择当前最佳的实现,它甚至可以组合静态字符串(“foo”+“bar”将成为单个“foobar”)。

我将明确分配 StringBuilder 的唯一地方是在 Loops 中(它在循环之前创建并在其中使用)。

如果您不确定会发生什么,请检查生成的字节码。

那么什么时候使用格式呢?当实际格式复杂时,我会使用格式。但是您现在正在谈论简单的串联。

于 2012-12-11T07:30:03.677 回答
1

我认为 String.Format 更有效,因为它具有以下优点,

  1. 提高可读性
  2. 更好的可译性
  3. 您可以在格式字符串中使用格式提供程序和简单的格式指示符(如固定宽度)。
  4. 您可以通过将格式字符串放入配置文件中来做一些强大的事情。
  5. String.Format() 通常更快,因为它在后台使用 StringBuilder 和高效的状态机,而 .Net 中的字符串连接相对较慢。当字符串的大小和替换值的数量增加时尤其如此。

谢谢。

于 2012-12-11T07:45:02.127 回答
0

我主要担心的String.format是它是特定于语言环境的操作,如果您的代码在不同的语言环境中运行,您最终可能会得到无法预料的结果。

我想有一个非语言环境替代它,因为它的紧凑语法非常好。

于 2013-09-05T14:07:55.787 回答