Работая в приложении Java, я недавно должен был собрать список значений, разделенных запятыми, для передачи в другой веб-сервис, не зная, сколько элементов будет заранее. Лучшее, что я мог придумать, это было примерно так:
public String appendWithDelimiter( String original, String addition, String delimiter ) {
if ( original.equals( "" ) ) {
return addition;
} else {
return original + delimiter + addition;
}
}
String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );
Я понимаю, что это не особенно эффективно, поскольку повсюду создаются строки, но я собирался сделать это для большей ясности, чем для оптимизации.
В Ruby я могу сделать что-то вроде этого, что выглядит намного элегантнее:
parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");
Но поскольку в Java нет команды соединения, я не смог найти ничего эквивалентного.
Итак, каков наилучший способ сделать это на Java?
Ответы:
Pre Java 8:
Apache commons lang - ваш друг здесь - он предоставляет метод соединения, очень похожий на тот, на который вы ссылаетесь в Ruby:
StringUtils.join(java.lang.Iterable,char)
Java 8:
Java 8 обеспечивает соединение из коробки через
StringJoiner
иString.join()
. Фрагменты ниже показывают, как вы можете их использовать:StringJoiner
String.join(CharSequence delimiter, CharSequence... elements))
String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
источник
Вы могли бы написать небольшой метод-метод в стиле соединения, который работает с java.util.Lists.
Тогда используйте это так:
источник
List<String>
свой инициализатор наIterator<?>
и иметь тот же эффект?В случае Android класс StringUtils из общего достояния недоступен, поэтому для этого я использовал
http://developer.android.com/reference/android/text/TextUtils.html
источник
В библиотеке Google Guava есть класс com.google.common.base.Joiner, который помогает решать такие задачи.
Образцы:
Вот статья о строковых утилитах Guava .
источник
В Java 8 вы можете использовать
String.join()
:Также взгляните на этот ответ для примера Stream API.
источник
Вы можете обобщить это, но в Java нет объединения, как вы хорошо сказали.
Это может работать лучше.
источник
Iterable<String>
и просто используйте тот факт, что вы можете итератор над ним. В вашем примере вам не нужно количество элементов в коллекции, так что это еще более общий вопрос.StringBuilder
вместо этого. Они идентичны, за исключением того, чтоStringBuffer
обеспечивают ненужную безопасность потока. Может кто-нибудь, пожалуйста, отредактируйте его!isEmpty()
метода, используйтеnext()
метод вместо этогов Java 8 вы можете сделать это следующим образом:
если в списке есть нули, вы можете использовать:
он также поддерживает префикс и суффикс:
источник
Используйте подход, основанный на
java.lang.StringBuilder
! («Изменчивая последовательность символов.»)Как вы упомянули, все эти объединения строк создают строки повсюду.
StringBuilder
не буду этого делатьПочему
StringBuilder
вместоStringBuffer
? ОтStringBuilder
Javadoc:источник
Я бы использовал Google Collections. Есть хорошая возможность присоединиться.
http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/base/Join.html
Но если бы я хотел написать это сам,
Я думаю, что это лучше работает с коллекцией объектов, так как теперь вам не нужно конвертировать ваши объекты в строки, прежде чем присоединиться к ним.
источник
Класс StringUtils Apache commons имеет метод соединения.
источник
Java 8
источник
Вы можете использовать
StringBuilder
тип Java для этого. Также естьStringBuffer
, но он содержит дополнительную логику безопасности потоков, которая часто не нужна.источник
И минимальный (если вы не хотите включать Apache Commons или Gauva в зависимости проекта только для объединения строк)
источник
Используйте StringBuilder и класс
Separator
Разделитель переносит разделитель. Разделитель возвращается разделителем
toString
, если только при первом вызове, который возвращает пустую строку!Исходный код для класса
Separator
источник
Separator
чтобы он использовалStringBuilder
вместо конкатенацииStrings
?Separator
просто возвращает разделитель, он не объединяет саму строку.Separator
??? Почему бы просто не использовать простую строку ...?!Почему бы не написать свой собственный метод join ()? В качестве параметров он будет принимать коллекцию Strings и разделитель String. Внутри метода переберите коллекцию и создайте свой результат в StringBuffer.
источник
Если вы используете Spring MVC, вы можете попробовать следующие шаги.
Это приведет к
a,b,c
источник
Если вы используете Eclipse Collections , вы можете использовать
makeString()
илиappendString()
.makeString()
возвращаетString
представление, аналогичноеtoString()
.Имеет три формы
makeString(start, separator, end)
makeString(separator)
по умолчанию начало и конец пустые строкиmakeString()
по умолчанию разделитель", "
(запятая и пробел)Пример кода:
appendString()
похожmakeString()
, но он добавляетAppendable
(какStringBuilder
) и естьvoid
. Он имеет те же три формы, с дополнительным первым аргументом, Присоединяемый.Если вы не можете преобразовать свою коллекцию в тип коллекций Eclipse, просто адаптируйте ее с помощью соответствующего адаптера.
Примечание: я являюсь коммиттером для коллекций Eclipse.
источник
Родной тип Java 8
Пользовательский объект Java 8:
источник
Вероятно, вам следует использовать метод
StringBuilder
withappend
для построения вашего результата, но в остальном это такое же хорошее решение, как и в Java.источник
Почему бы вам не сделать в Java то же самое, что вы делаете в ruby, то есть создать разделенную разделителем строку только после того, как вы добавили все части в массив?
Вы можете переместить этот цикл for в отдельный вспомогательный метод, а также использовать StringBuilder вместо StringBuffer ...
Редактировать : исправлен порядок добавления.
источник
Благодаря переменным аргументам Java 5 вам не нужно явно вставлять все строки в коллекцию или массив:
источник
Для тех, кто в контексте Spring их StringUtils класс полезен:
Есть много полезных ярлыков, таких как:
и многие другие.
Это может быть полезно, если вы еще не используете Java 8 и уже находитесь в контексте Spring.
Я предпочитаю это против Apache Commons (хотя и очень хорошо) для поддержки Коллекции, которая проще как это:
источник
Вы можете попробовать что-то вроде этого:
источник
В общем, как-то так:
источник
Не знаю, действительно ли это лучше, но, по крайней мере, он использует StringBuilder, который может быть немного более эффективным.
Ниже приведен более общий подход, если вы можете создать список параметров ДО выполнения каких-либо разделителей параметров.
источник
Ваш подход не так уж плох, но вы должны использовать StringBuffer вместо знака +. + Имеет большой недостаток в том, что для каждой отдельной операции создается новый экземпляр String. Чем длиннее ваша строка, тем больше накладные расходы. Так что использование StringBuffer должно быть самым быстрым способом:
После того, как вы закончили создание вашей строки, просто вызовите toString () для возвращенного StringBuffer.
источник
Вместо использования конкатенации строк, вы должны использовать StringBuilder, если ваш код не является многопоточным, и StringBuffer, если это так.
источник
Вы делаете это немного сложнее, чем должно быть. Давайте начнем с конца вашего примера:
С небольшим изменением использования StringBuilder вместо String это становится:
Когда вы закончите (я предполагаю, что вы должны проверить и несколько других условий), просто убедитесь, что вы удаляете запятую с помощью такой команды:
И наконец, получите строку, которую вы хотите с
Вы также можете заменить «,» во втором вызове, чтобы добавить общую строку-разделитель, которая может быть установлена на что угодно. Если у вас есть список вещей, которые, как вы знаете, нужно добавить (безоговорочно), вы можете поместить этот код в метод, который принимает список строк.
источник
источник
Итак, пара вещей, которые вы могли бы сделать, чтобы создать ощущение, будто вы ищете:
1) Расширьте класс List - и добавьте к нему метод соединения. Метод join будет просто выполнять конкатенацию и добавление разделителя (который может быть параметром метода join)
2) Похоже, что в Java 7 будут добавлены методы расширения для java, что позволит вам просто прикрепить определенный метод к классу: вы можете написать этот метод join и добавить его в качестве метода расширения в List или даже в Коллекция.
Решение 1, вероятно, является единственным реалистичным, хотя, поскольку Java 7 еще не выпущена :) Но он должен работать просто отлично.
Чтобы использовать оба из них, вы просто добавляете все свои элементы в Список или Коллекцию как обычно, а затем вызываете новый пользовательский метод, чтобы «присоединиться» к ним.
источник