Есть ли способ построить строку Java, используя функцию форматирования в стиле SLF4J?

Я слышал, что использование 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 над такой библиотекой, если она существует?

Ответ 1

Для конкатенации строк один раз старый надежный "str" + param + "other str" отлично работает (он фактически преобразуется компилятором в StringBuilder).

StringBuilders в основном полезны, если вам нужно продолжать добавлять вещи в строку, но вы не можете заставить их все в один оператор. Например, возьмите цикл 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

Несмотря на то, что принятый ответ хорош, если (как и я), вас интересует именно семантика стиля Slf4J, то правильным решением является использование Slf4J MessageFormatter

Вот пример фрагмента использования:

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

(Обратите внимание, что в этом примере отбрасывается последний аргумент типа Throwable)

Ответ 3

Кроме того, в min стоит отметить, что String.format() является плохой реализацией sprintf с использованием регулярных выражений, поэтому если вы профилируете свой код, вы увидите шаблоны и int [], которые вы не ожидали. MessageFormat и slf MessageFormmater обычно быстрее и выделяют меньше мусора