有没有办法使用 SLF4J 风格的格式化函数构建 Java 字符串?

问题描述 投票:0回答:3

我听说使用 StringBuilder 比使用字符串连接更快,但我厌倦了一直与 StringBuilder 对象较量。我最近接触了 SLF4J 日志库,与 String.format 相比,我喜欢它的格式“只做正确的事”的简单性。有没有一个图书馆可以让我写一些类似的东西:

int myInteger = 42;
MyObject myObject = new MyObject();  // Overrides toString()
String result = CoolFormatingLibrary.format("Simple way to format {} and {}",
    myInteger, myObject);

此外,是否有任何原因(包括性能,但不包括日期和有效数字格式的细粒度控制)为什么我可能想要在这样的库上使用 String.format(如果确实存在)?

java string string-formatting
3个回答
47
投票

虽然接受的答案很好,但如果(像我一样)有人对 Slf4J 风格的语义感兴趣,那么正确的解决方案是使用 Slf4J 的 MessageFormatter

这是一个示例用法片段:

public static String format(String format, Object... params) {
    return MessageFormatter.arrayFormat(format, params).getMessage();
}

(请注意,此示例丢弃最后一个类型为

Throwable
的参数)


9
投票

对于连接字符串一次性,旧的可靠的

"str" + param + "other str"
完全没问题(它实际上被编译器转换为
StringBuilder
)。

如果您必须不断向字符串添加内容,但无法将它们全部放入一个语句中,则 StringBuilder 主要有用。例如,采用

for
循环:

String str = "";
for (int i = 0; i < 1000000; i++) {
    str += i + " "; // ignoring the last-iteration problem
}

这将比等效的 StringBuilder 版本运行得慢得多:

StringBuilder sb = new StringBuilder(); // for extra speed, define the size
for (int i = 0; i < 1000000; i++) {
    sb.append(i).append(" ");
}
String str = sb.toString();

但这两个在功能上是等价的:

String str = var1 + " " + var2;
String str2 = new StringBuilder().append(var1).append(" ").append(var2).toString();

说了这么多,我真正的答案是:

查看

java.text.MessageFormat
。 Javadocs 中的示例代码:

int fileCount = 1273;
String diskName = "MyDisk";
Object[] testArgs = {new Long(fileCount), diskName};

MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0} file(s).");

System.out.println(form.format(testArgs));

输出:

The disk "MyDisk" contains 1,273 file(s).

还有一个静态

format
方法,不需要创建
MessageFormat
对象。

所有此类库都将归结为最基本的字符串连接,因此彼此之间不会有太大的性能差异。


2
投票

另外值得注意的是,String.format() 是使用正则表达式完成的 sprintf 的一个糟糕实现,因此,如果您分析代码,您将看到您不期望的模式和 int[] 。 MessageFormat 和 slf MessageFormatter 通常速度更快并且分配的垃圾更少

© www.soinside.com 2019 - 2024. All rights reserved.