Вопрос-ответ

What's the best way to build a string of delimited items in Java?

Какой наилучший способ создать строку из элементов с разделителями в Java?

Недавно во время работы в приложении 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 отсутствует команда join , я не смог придумать ничего эквивалентного.

Итак, какой лучший способ сделать это в Java?

Переведено автоматически
Ответ 1

Версия до Java 8:

Язык commons lang от Apache здесь ваш друг - он предоставляет метод join, очень похожий на тот, на который вы ссылаетесь в Ruby:

StringUtils.join(java.lang.Iterable,char)


Java 8:

Java 8 обеспечивает соединение "из коробки" с помощью StringJoiner и String.join(). Приведенные ниже фрагменты показывают, как вы можете их использовать:

StringJoiner

StringJoiner joiner = new StringJoiner(",");
joiner.add("01").add("02").add("03");
String joinedString = joiner.toString(); // "01,02,03"

String.join(CharSequence delimiter, CharSequence... elements))

String joinedString = String.join(" - ", "04", "05", "06"); // "04 - 05 - 06"

String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)

List<String> strings = new LinkedList<>();
strings.add("Java");strings.add("is");
strings.add("cool");
String message = String.join(" ", strings);
//message returned is: "Java is cool"
Ответ 2

Вы могли бы написать небольшой служебный метод в стиле join, который работает на java.util.Списки

public static String join(List<String> list, String delim) {

StringBuilder sb = new StringBuilder();

String loopDelim = "";

for(String s : list) {

sb.append(loopDelim);
sb.append(s);

loopDelim = delim;
}

return sb.toString();
}

Затем используйте это следующим образом:

    List<String> list = new ArrayList<String>();

if( condition ) list.add("elementName");
if( anotherCondition ) list.add("anotherElementName");

join(list, ",");
Ответ 3

В случае Android класс StringUtils из commons недоступен, поэтому для этого я использовал

android.text.TextUtils.join(CharSequence delimiter, Iterable tokens)

http://developer.android.com/reference/android/text/TextUtils.html

Ответ 4

В библиотеке Google Guava есть com.google.common.base.Joiner класс, который помогает решать такие задачи.

Примеры:

"My pets are: " + Joiner.on(", ").join(Arrays.asList("rabbit", "parrot", "dog")); 
// returns "My pets are: rabbit, parrot, dog"

Joiner.on(" AND ").join(Arrays.asList("field1=1" , "field2=2", "field3=3"));
// returns "field1=1 AND field2=2 AND field3=3"

Joiner.on(",").skipNulls().join(Arrays.asList("London", "Moscow", null, "New York", null, "Paris"));
// returns "London,Moscow,New York,Paris"

Joiner.on(", ").useForNull("Team held a draw").join(Arrays.asList("FC Barcelona", "FC Bayern", null, null, "Chelsea FC", "AC Milan"));
// returns "FC Barcelona, FC Bayern, Team held a draw, Team held a draw, Chelsea FC, AC Milan"

Вот статья о строковых утилитах Guava.

java string algorithm