14

我目前正在使用 java 编写一个 MUD(基于文本的游戏)。MUD 的主要方面之一是格式化字符串并将其发送回用户。这将如何最好地完成?

假设我想发送以下字符串:

你对某人说“你好!” - 其中“某人”、“说”和“你好!” 都是变量。哪个是最好的性能明智的?

"You " + verb + " to " + user + " \"" + text + "\""

或者

String.format("You %1$s to %2$s \"%3$s\"", verb, user, text)

或其他选择?

我不确定最终哪个会更容易使用(这很重要,因为它无处不在),但我现在正在考虑它,因为与 + 连接有点令人困惑一些较大的线路。我觉得在这种情况下使用 StringBuilder 只会使它更不可读。

这里有什么建议吗?

4

8 回答 8

27

如果字符串是使用单个连接表达式构建的;例如

String s = "You " + verb + " to " + user + " \"" + text + "\"";

那么这或多或少相当于更冗长的:

StringBuilder sb = new StringBuilder();
sb.append("You");
sb.append(verb);
sb.append(" to ");
sb.append(user);
sb.append(" \"");
sb.append(text );
sb.append('"');
String s = sb.toString();

(其实Java编译器会把前者编译成后者……差不多。)

当您开始创建中间字符串或使用+=等构建字符串时,效率问题就会出现。在这一点上,StringBuilder变得更有效率,因为您减少了创建然后丢弃的中间字符串的数量。

现在,当您使用 时String.format(),它应该StringBuilder在引擎盖下使用。但是,format每次调用时还必须解析字符串格式,如果您以最佳方式构建字符串,则不会产生这种开销。


话虽如此,我的建议是以最易读的方式编写代码。如果分析告诉您这是一个真正的性能问题,则只需担心构建字符串的最有效方法。(现在,您正在花时间思考如何解决可能变得微不足道或无关紧要的性能问题。)

另一个答案提到使用格式字符串可以简化对多种语言的支持。确实如此,尽管对于诸如复数、性别等之类的事情你可以做些什么是有限制的。

于 2011-10-15T03:42:26.613 回答
1

我认为连接 with+比使用String.format.

String.format当您需要格式化数字和日期时很好。

于 2011-10-15T18:28:12.487 回答
1

保持简单的关键是永远不要看它。这就是我的意思:

Joiner join = Joiner.on(" ");

public void constructMessage(StringBuilder sb, Iterable<String> words) {
  join.appendTo(sb, words);
}

我正在使用 Guava Joiner 类使可读性成为非问题。还有什么比“加入”更清楚的呢?所有关于连接的讨厌的部分都被很好地隐藏起来了。通过使用 Iterable,我可以将这种方法用于各种数据结构,列表是最明显的。

这是一个使用 Guava ImmutableList 的调用示例(它比常规列表更有效,因为任何修改列表的方法都只会抛出异常,并且正确地表示了constructMessage() 无法更改单词列表的事实,只需消耗它):

StringBuilder outputMessage = new StringBuilder();
constructMessage(outputMessage, 
         new ImmutableList.Builder<String>()
            .add("You", verb, "to", user, "\"", text, "\"")
            .build());
于 2011-10-15T04:08:52.207 回答
1

与加号连接,编译器可以以执行方式转换代码。使用字符串格式我不知道。

我更喜欢与 plus 连接,我认为这更容易理解。

于 2011-10-15T02:45:46.043 回答
0

我认为 String.format 看起来更干净。但是,您可以使用 StringBuilder 并使用 append 函数来创建您想要的字符串

于 2011-10-15T02:45:44.507 回答
0

老实说,如果您想减少打字,我建议您使用第一个,如果您正在寻找一种更 C 风格的方式,则建议您使用后一个。

我在这里坐了一两分钟,思考可能是什么问题,但我认为这取决于你想输入多少。

还有人有想法吗?

于 2011-10-15T02:47:51.337 回答
0

假设您要经常重用基本字符串 将您的模板存储为

String mystring = "你 $1 到 $2 \"$3\""

然后只需获取一份副本并用您想要的内容替换 $X 即可。

这也适用于资源文件。

于 2011-10-15T02:48:54.873 回答
-3

最好的,性能方面的,可能是使用 StringBuffer。

于 2011-10-15T02:50:57.213 回答