Java concatenate для создания строки или формата

В настоящий момент я пишу MUD (текстовую игру), используя java. Одним из основных аспектов MUD является форматирование строк и отправка его обратно пользователю. Как это лучше всего сделать?

Скажем, я хочу отправить следующую строку:

Ты говоришь кому-то "Привет!" - где "Кто-то", "сказать" и "Привет!" все переменные. Что было бы лучше всего по производительности?

"You " + verb + " to " + user + " \"" + text + "\""

или

String.format("You %1$s to %2$s \"%3$s\"", verb, user, text)

или какой-либо другой вариант?

Я не уверен, что в конце концов это будет проще использовать (что важно, потому что оно будет везде), но я думаю об этом в этот момент, потому что конкатенация с + немного запутывает с некоторыми из больших линий. Я считаю, что использование StringBuilder в этом случае просто сделает его еще менее удобочитаемым.

Любое предложение здесь?

Ответ 1

Если строки построены с использованием одного выражения конкатенации; например.

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 также должен анализировать формат String каждый раз, когда вы совершаете вызов, и это накладные расходы, которые у вас нет, если вы построите строку оптимально.


Сказав это, Мой совет должен был написать код так, как это наиболее читаемо. Только беспокоиться о наиболее эффективном способе построения строк, если профилирование говорит вам, что это реальная проблема с производительностью. (Прямо сейчас вы тратите время на размышления о способах решения проблемы производительности, которая может оказаться незначительной или несущественной.)

В другом ответе упоминается, что использование строки формата может упростить поддержку нескольких языков. Это правда, хотя существуют ограничения относительно того, что вы можете делать в отношении таких вещей, как множественное число, гендерные группы и т.д.

Ответ 2

Взаимодействие с плюсом, compilet может преобразовать код в простейшем виде. Со строковым форматом я не знаю.

Я предпочитаю кокатинацию с плюсом, я думаю, что это проще для нижнего уровня.

Ответ 3

Ключом к простоте в том, чтобы никогда не смотреть на него. Вот что я имею в виду:

Joiner join = Joiner.on(" ");

public void constructMessage(StringBuilder sb, Iterable<String> words) {
  join.appendTo(sb, words);
}

Я использую класс Guava Joiner для обеспечения удобочитаемости без проблем. Что может быть яснее, чем "присоединиться"? Все неприятные битки относительно конкатенации красиво скрыты. Используя Iterable, я могу использовать этот метод со всеми видами структур данных, списки наиболее очевидны.

Вот пример вызова с использованием Guava ImmutableList (который более эффективен, чем обычный список, поскольку любые методы, которые изменяют список, просто бросают исключения и правильно отображают тот факт, что constructMessage() не может изменить список слов, просто используйте его):

StringBuilder outputMessage = new StringBuilder();
constructMessage(outputMessage, 
         new ImmutableList.Builder<String>()
            .add("You", verb, "to", user, "\"", text, "\"")
            .build());

Ответ 4

Я думаю, что String.format выглядит чище. Однако вы можете использовать StringBuilder и использовать функцию добавления для создания желаемой строки.

Ответ 5

Я буду честен и предлагаю, чтобы вы взяли первый, если хотите меньше набирать текст, или последний, если вы ищете более C-стиль для этого.

Я сидел здесь минутку, размышляя над тем, что может быть проблемой, но я думаю, что все зависит от того, как вы хотите напечатать.

У кого-нибудь есть идея?

Ответ 6

Предполагая, что вы собираетесь повторно использовать базовые строки, часто храните свои шаблоны, например

String mystring = "Вы от $1 до $2 \" $3\""

Затем просто получите копию и замените $X тем, что вы хотите.

Это тоже будет очень полезно для файла ресурсов.

Ответ 7

Я думаю, что конкатенация с + более читаема, чем использование String.format.

String.format хорош, когда вам нужно отформатировать число и даты.

Ответ 9

Лучшим, с точки зрения производительности, вероятно, будет использование StringBuffer.