Java 连接以构建字符串或格式
我现在正在使用java编写一个MUD(基于文本的游戏)。 MUD 的主要方面之一是格式化字符串并将其发送回用户。如何最好地实现这一点?
假设我想发送以下字符串:
您对某人说“你好!” - 其中“某人”、“说”和“你好!”都是变量。哪个性能最好?
"You " + verb + " to " + user + " \"" + text + "\""
或
String.format("You %1$s to %2$s \ “%3$s\”“,动词,用户,文本)
或其他选项?
我不确定最终哪个会更容易使用(这很重要,因为它会无处不在),但我现在正在考虑它,因为与 + 连接有点令人困惑一些较大的线路。我觉得在这种情况下使用 StringBuilder 只会使其可读性更差。
这里有什么建议吗?
I'm writing a MUD (text based game) at the moment using java. One of the major aspects of a MUD is formatting strings and sending it back to the user. How would this best be accomplished?
Say I wanted to send the following string:
You say to Someone "Hello!" - where "Someone", "say" and "Hello!" are all variables. Which would be best performance wise?
"You " + verb + " to " + user + " \"" + text + "\""
or
String.format("You %1$s to %2$s \"%3$s\"", verb, user, text)
or some other option?
I'm not sure which is going to be easier to use in the end (which is important because it'll be everywhere), but I'm thinking about it at this point because concatenating with +'s is getting a bit confusing with some of the bigger lines. I feel that using StringBuilder in this case will simply make it even less readable.
Any suggestion here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果字符串是使用单个串联表达式构建的;例如
,这或多或少相当于更冗长的内容:
事实上,经典的Java编译器会将前者编译为后者......几乎。在 Java 9 中,他们实现了 JEP 280,它替换了字节码中构造函数和方法调用的顺序使用单个
invokedynamic
字节码。然后运行时系统会优化此1。当您开始创建中间字符串或使用
+=
等构建字符串时,就会出现效率问题。在某些情况下,使用显式StringBuilder
可以2提高效率,因为您可以减少复制量。现在,当您使用
String.format()
时,它应该在幕后使用StringBuilder
。但是,format
还必须在每次调用时解析格式字符串,如果您以最佳方式构建字符串,则不会有这种开销。话虽如此,我的建议是以最具可读性的方式编写代码。如果分析告诉您这是一个真正的性能问题,则只需担心构建字符串的最有效方法。 (现在,您正在花时间思考解决性能问题的方法,这可能是无关紧要或无关紧要的。)
另一个答案提到使用格式字符串可以简化对多种语言的支持。这是事实,尽管您在复数、性别等方面可以做的事情是有限的。
1 - 因此,对于 Java 9 或更高版本,上面示例中的手动优化实际上可能会产生负面后果。但这是您每次进行微优化时都要承担的风险。
2 - 分析和预测这种情况何时发生通常是很困难的。
If the strings are built using a single concatenation expression; e.g.
then this is more or less equivalent to the more long winded:
In fact, a classic Java compiler will compile the former into the latter ... almost. In Java 9, they implemented JEP 280 which replaces the sequence of constructor and method calls in the bytecodes with a single
invokedynamic
bytecode. The runtime system then optimizes this1.The efficiency issues arise when you start creating intermediate strings, or building strings using
+=
and so on. In some cases, using an explicitStringBuilder
can be2 more efficient because you are reduce the amount of copying.Now when you use
String.format()
, it should be using aStringBuilder
under the hood. However,format
also has to parse the format String each time you make the call, and that is an overhead you don't have if you do the string building optimally.Having said this, My Advice would be to write the code in the way that is most readable. Only worry about the most efficient way to build strings if profiling tells you that this is a real performance concern. (Right now, you are spending time thinking about ways to address a performance issue that may turn out to be insignificant or irrelevant.)
Another answer mentions that using a format string may simplify support for multiple languages. This is true, though there are limits as to what you can do with respect to such things as plurals, genders, and so on.
1 - As a consequence, hand optimization as per the example above might actually have negative consequences, for Java 9 or later. But this is a risk you take whenever you micro-optimize.
2 - Analyzing and predicting when this happens in general is difficult.
我认为使用
+
连接比使用String.format
更具可读性。当您需要格式化数字和日期时,
String.format
非常有用。I think that concatenation with
+
is more readable than usingString.format
.String.format
is good when you need to format number and dates.与 plus 连接,编译器可以以性能方式转换代码。对于字符串格式我不知道。
我更喜欢与 plus 并置,我认为这样更容易理解。
Concateneting with plus, the compilet can transforms the code in performatic way. With string format i don t know.
I prefer cocatenation with plus, i think that is easer to undersand.
保持简单的关键是永远不要看它。我的意思是:
我使用 Guava Joiner 类来使可读性不再是问题。还有什么比“加入”更清楚的呢?所有与串联有关的令人讨厌的部分都被很好地隐藏起来。通过使用 Iterable,我可以将此方法用于各种数据结构,列表是最明显的。
下面是一个使用 Guava ImmutableList 的调用示例(它比常规列表更有效,因为任何修改列表的方法都会抛出异常,并且正确地表示了一个事实:constructMessage() 无法更改单词列表,只需使用它):
The key to keeping it simple is to never look at it. Here is what I mean:
I'm using the Guava Joiner class to make readability a non-issue. What could be clearer than "join"? All the nasty bits regarding concatenation are nicely hidden away. By using Iterable, I can use this method with all sorts of data structures, Lists being the most obvious.
Here is an example of a call using a Guava ImmutableList (which is more efficient than a regular list, since any methods that modify the list just throw exceptions, and correctly represents the fact that constructMessage() cannot change the list of words, just consume it):
老实说,如果您想要更少的打字,我建议您选择第一个,或者如果您正在寻找一种更 C 风格的方式来完成它,则选择后一个。
我坐在这里一两分钟思考可能出现问题的想法,但我认为这取决于您想输入多少内容。
还有其他人有想法吗?
I will be honest and suggest that you take the first one if you want less typing, or the latter one if you are looking for a more C-style way of doing it.
I sat here for a minute or two pondering the idea of what could be a problem, but I think it comes down to how much you want to type.
Anyone else have an idea?
假设您要经常重用基本字符串存储您的模板,例如
String mystring = "You $1 to $2 \"$3\""
然后只需获取副本并用您想要的内容替换 $X 。
这对于资源文件也非常有效。
Assuming you are going to reuse base strings often Store your templates like
String mystring = "You $1 to $2 \"$3\""
Then just get a copy and do a replace $X with what you want.
This would work really well for a resource file too.
我认为 String.format 看起来更干净。
但是,您可以使用 StringBuilder 并使用追加函数来创建您想要的字符串
I think String.format looks cleaner.
However you can use StringBuilder and use append function to create the string you want
从性能角度来看,最好的可能是使用 StringBuffer。
The best, performance-wise, would probably be to use a StringBuffer.