Java объединяет для создания строки или формата - PullRequest
11 голосов
/ 15 октября 2011

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

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

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

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

или

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

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

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

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

Ответы [ 8 ]

21 голосов
/ 15 октября 2011

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

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


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

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

1 голос
/ 15 октября 2011

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

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());
1 голос
/ 15 октября 2011

Конкатетинируя с плюсом, компилятор может преобразовать код в производительную форму. С форматом строки я не знаю.

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

0 голосов
/ 15 октября 2011

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

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

0 голосов
/ 15 октября 2011

Лучше всего было бы использовать StringBuffer.

0 голосов
/ 15 октября 2011

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

String mystring = "Вы от 1 до 2 долларов", 3 100 долларов *

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

Это очень хорошо подойдет и для файла ресурсов.

0 голосов
/ 15 октября 2011

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

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

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

0 голосов
/ 15 октября 2011

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

...