Java连接以生成字符串或格式
我正在用java编写一个基于文本的游戏。MUD的一个主要方面是格式化字符串并将其发送回用户。如何最好地实现这一点 假设我想发送以下字符串: 你对某人说“你好!”-其中“某人”、“说”和“你好!”都是变量。哪种性能最好Java连接以生成字符串或格式,java,string-formatting,string-concatenation,mud,Java,String Formatting,String Concatenation,Mud,我正在用java编写一个基于文本的游戏。MUD的一个主要方面是格式化字符串并将其发送回用户。如何最好地实现这一点 假设我想发送以下字符串: 你对某人说“你好!”-其中“某人”、“说”和“你好!”都是变量。哪种性能最好 “您”+动词+”到“+用户+”\“”+文本+“\“” 或 String.format(“您%1$s到%2$s\%3$s\”,动词,用户,文本) 还是其他选择 我不确定最终哪一行会更容易使用(这很重要,因为它无处不在),但我在考虑这一点,因为用+连接会让一些更大的行变得有点混乱。我觉
“您”+动词+”到“+用户+”\“”+文本+“\“”
或
String.format(“您%1$s到%2$s\%3$s\”,动词,用户,文本)
还是其他选择
我不确定最终哪一行会更容易使用(这很重要,因为它无处不在),但我在考虑这一点,因为用+连接会让一些更大的行变得有点混乱。我觉得在这种情况下使用StringBuilder只会使它更不可读
这里有什么建议吗?我觉得String.format看起来更干净。
但是,您可以使用StringBuilder和append函数来创建所需的字符串与plus连接,编译器可以以执行方式转换代码。用字符串格式我不知道
我更喜欢与plus联合,我认为这比undersand更容易 老实说,如果你想少打字,我建议你选择第一种,如果你想找一种更C风格的方式,我建议你选择后一种 我在这里坐了一两分钟,思考什么可能是个问题,但我认为这取决于你想输入多少
其他人有什么想法吗?假设您要重用基本字符串,则通常将模板存储为 String mystring=“您需要$1到$2\”$3“ 然后,只需获得一份副本,并用您想要的替换$X即可
这对于资源文件也非常有效。从性能角度来看,最好的方法可能是使用StringBuffer。如果字符串是使用单个串联表达式构建的;e、 g
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
在每次调用时还必须解析格式字符串,如果以最佳方式构建字符串,则不会产生开销
话虽如此,我的建议是以最具可读性的方式编写代码。如果分析告诉您这是一个真正的性能问题,那么只需要担心构建字符串的最有效方法。(现在,您正在花时间思考解决性能问题的方法,这些问题可能变得无关紧要或无关紧要。)
另一个答案提到使用格式字符串可以简化对多种语言的支持。这是真的,尽管在复数、性别等方面你可以做的事情是有限的。保持简单的关键是永远不要看它。我的意思是:
Joiner join = Joiner.on(" ");
public void constructMessage(StringBuilder sb, Iterable<String> words) {
join.appendTo(sb, words);
}
Joiner join=Joiner.on(“”);
公共消息(StringBuilder sb,可编辑文字){
附加于(某人,词语);
}
我使用Guava Joiner类使可读性成为一个非问题。还有什么比“加入”更清楚?所有关于连接的讨厌的地方都被很好地隐藏起来了。通过使用Iterable,我可以将此方法用于各种数据结构,列表是最明显的
下面是一个使用Guava ImmutableList的调用示例(它比常规列表更有效,因为任何修改列表的方法都会抛出异常,并且正确地表示constructMessage()无法更改单词列表,只需使用它):
StringBuilder outputMessage=new StringBuilder();
constructMessage(输出消息,
新建ImmutableList.Builder()
.add(“您”,动词,“to”,用户“\”,文本“\”)
.build());
我认为使用+
进行连接比使用String.format
更具可读性
String.format
在需要格式化数字和日期时很好。此外,您还可以支持多种语言:我的理由更多是关于可读性。我已经习惯于输入“stuff”+“other stuff”,如果我选择另一个选项,我可能不得不改掉这个习惯。我最初的想法是“You[verb]to[user][text]”,然后做一个replaceall(类驱动,所以我会添加setElement(“verb”,verb)之类的变量,然后它会吐回一个格式化的字符串),但我无意中发现了。格式化和计算我最初的想法在性能上会很糟糕(但非常容易阅读)。我不同意。从javadoc:在可能的情况下,建议优先使用该类而不是StringBuffer
,因为在大多数实现中,它会更快。--顺便说一句,我怀疑字符串连接是这种应用程序的瓶颈。同样的区别,一个是同步的,另一个不是。当正确实现同步时,如果没有争用,则差异可以忽略不计。(而且,很明显,如果存在争用,人们不希望使用StringBuilder。)不要担心性能,除非您发现这是一个问题,并且这是一个瓶颈。做任何你认为会产生可读性和可维护性最好的代码的事情。谢谢你的详细解释,它帮助我把事情想清楚了。我将使用String.format,因为它是a)一个内置的解决方案,b)通过使字符串更简单,已经使我的生活更轻松了
StringBuilder outputMessage = new StringBuilder();
constructMessage(outputMessage,
new ImmutableList.Builder<String>()
.add("You", verb, "to", user, "\"", text, "\"")
.build());