Is there a way to build a Java String using an SLF4J-style formatting function?

主宰稳场 提交于 2019-12-04 16:26:52

问题


I've heard that using StringBuilder is faster than using string concatenation, but I'm tired of wrestling with StringBuilder objects all of the time. I was recently exposed to the SLF4J logging library and I love the "just do the right thing" simplicity of its formatting when compared with String.format. Is there a library out there that would allow me to write something like:

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

Also, is there any reason (including performance but excluding fine-grained control of date and significant digit formatting) why I might want to use String.format over such a library if it does exist?


回答1:


For concatenating strings one time, the old reliable "str" + param + "other str" is perfectly fine (it's actually converted by the compiler into a StringBuilder).

StringBuilders are mainly useful if you have to keep adding things to the string, but you can't get them all into one statement. For example, take a for loop:

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

This will run much slower than the equivalent StringBuilder version:

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();

But these two are functionally equivalent:

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

Having said all that, my actual answer is:

Check out java.text.MessageFormat. Sample code from the 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));

Output:

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

There is also a static format method which does not require creating a MessageFormat object.

All such libraries will boil down to string concatenation at their most basic level, so there won't be much performance difference from one to another.




回答2:


Although the Accepted answer is good, if (like me) one is interested in exactly Slf4J-style semantics, then the correct solution is to use Slf4J's MessageFormatter

Here is an example usage snippet:

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

(Note that this example discards a last argument of type Throwable)




回答3:


Plus it worth bearing in min that String.format() is a bad implementation of sprintf done with regexps, so if you profile your code you will see an patterns and int[] that you were not expecting. MessageFormat and the slf MessageFormmater are generally faster and allocate less junk




回答4:


You can already do this, using the built-in Java String class.



来源:https://stackoverflow.com/questions/3114021/is-there-a-way-to-build-a-java-string-using-an-slf4j-style-formatting-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!