Каков наилучший способ создать строку элементов с разделителями в Java? - PullRequest
275 голосов
/ 15 сентября 2008

Работая в приложении 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?

Ответы [ 35 ]

1 голос
/ 16 апреля 2018

Java 8 Native Type

List<Integer> example;
example.add(1);
example.add(2);
example.add(3);
...
example.stream().collect(Collectors.joining(","));

Пользовательский объект Java 8:

List<Person> person;
...
person.stream().map(Person::getAge).collect(Collectors.joining(","));
1 голос
/ 21 января 2015

Для тех, кто находится в контексте Spring, их класс StringUtils также полезен:

Есть много полезных ярлыков, таких как:

  • collectionToCommaDelimitedString (Collection coll)
  • collectionToDelimitedString (Collection coll, String delim)
  • arrayToDelimitedString (Object [] arr, String delim)

и многие другие.

Это может быть полезно, если вы еще не используете Java 8 и уже находитесь в контексте Spring.

Я предпочитаю это против Apache Commons (хотя и очень хорошо) для поддержки Коллекции, которая проще как это:

// Encoding Set<String> to String delimited 
String asString = org.springframework.util.StringUtils.collectionToDelimitedString(codes, ";");

// Decoding String delimited to Set
Set<String> collection = org.springframework.util.StringUtils.commaDelimitedListToSet(asString);
0 голосов
/ 15 сентября 2008
//Note: if you have access to Java5+, 
//use StringBuilder in preference to StringBuffer.  
//All that has to be replaced is the class name.  
//StringBuffer will work in Java 1.4, though.

appendWithDelimiter( StringBuffer buffer, String addition, 
    String delimiter ) {
    if ( buffer.length() == 0) {
        buffer.append(addition);
    } else {
        buffer.append(delimiter);
        buffer.append(addition);
    }
}


StringBuffer parameterBuffer = new StringBuffer();
if ( condition ) { 
    appendWithDelimiter(parameterBuffer, "elementName", "," );
}
if ( anotherCondition ) {
    appendWithDelimiter(parameterBuffer, "anotherElementName", "," );
}

//Finally, to return a string representation, call toString() when returning.
return parameterBuffer.toString(); 
0 голосов
/ 21 августа 2016

Лично я довольно часто использую следующее простое решение для регистрации:

List lst = Arrays.asList("ab", "bc", "cd");
String str = lst.toString().replaceAll("[\\[\\]]", "");
0 голосов
/ 15 сентября 2008

Вы можете попробовать что-то вроде этого:

StringBuilder sb = new StringBuilder();
if (condition) { sb.append("elementName").append(","); }
if (anotherCondition) { sb.append("anotherElementName").append(","); }
String parameterString = sb.toString();
0 голосов
/ 15 сентября 2008
public static String join(String[] strings, char del)
{
    StringBuffer sb = new StringBuffer();
    int len = strings.length;
    boolean appended = false;
    for (int i = 0; i < len; i++)
    {
        if (appended)
        {
            sb.append(del);
        }
        sb.append(""+strings[i]);
        appended = true;
    }
    return sb.toString();
}
0 голосов
/ 19 марта 2015

Исправить ответ Роб Дикерсон.

Это проще в использовании:

public static String join(String delimiter, String... values)
{
    StringBuilder stringBuilder = new StringBuilder();

    for (String value : values)
    {
        stringBuilder.append(value);
        stringBuilder.append(delimiter);
    }

    String result = stringBuilder.toString();

    return result.isEmpty() ? result : result.substring(0, result.length() - 1);
}
0 голосов
/ 15 сентября 2008

Так что в принципе как то так:

public static String appendWithDelimiter(String original, String addition, String delimiter) {

if (original.equals("")) {
    return addition;
} else {
    StringBuilder sb = new StringBuilder(original.length() + addition.length() + delimiter.length());
        sb.append(original);
        sb.append(delimiter);
        sb.append(addition);
        return sb.toString();
    }
}
0 голосов
/ 15 сентября 2008

Ваш подход не так уж плох, но вы должны использовать StringBuffer вместо знака +. + Имеет большой недостаток в том, что для каждой отдельной операции создается новый экземпляр String. Чем длиннее ваша строка, тем больше накладные расходы. Таким образом, использование StringBuffer должно быть самым быстрым способом:

public StringBuffer appendWithDelimiter( StringBuffer original, String addition, String delimiter ) {
        if ( original == null ) {
                StringBuffer buffer = new StringBuffer();
                buffer.append(addition);
                return buffer;
        } else {
                buffer.append(delimiter);
                buffer.append(addition);
                return original;
        }
}

После того, как вы закончили создание вашей строки, просто вызовите toString () для возвращенного StringBuffer.

0 голосов
/ 15 сентября 2008

Не знаю, действительно ли это лучше, но, по крайней мере, он использует StringBuilder, который может быть немного более эффективным.

Ниже приведен более общий подход, если вы можете создать список параметров ДО выполнения каких-либо разделителей параметров.

// Answers real question
public String appendWithDelimiters(String delimiter, String original, String addition) {
    StringBuilder sb = new StringBuilder(original);
    if(sb.length()!=0) {
        sb.append(delimiter).append(addition);
    } else {
        sb.append(addition);
    }
    return sb.toString();
}


// A more generic case.
// ... means a list of indeterminate length of Strings.
public String appendWithDelimitersGeneric(String delimiter, String... strings) {
    StringBuilder sb = new StringBuilder();
    for (String string : strings) {
        if(sb.length()!=0) {
            sb.append(delimiter).append(string);
        } else {
            sb.append(string);
        }
    }

    return sb.toString();
}

public void testAppendWithDelimiters() {
    String string = appendWithDelimitersGeneric(",", "string1", "string2", "string3");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...