Самый сложный путь к созданию разделенных от запятой Строк от Набора/Массива/Списка?

97
задан bluish 7 April 2011 в 07:10
поделиться

15 ответов

Так как строки неизменны, можно хотеть использовать класс StringBuilder, если Вы собираетесь изменить Строку в коде.

класс StringBuilder может рассматриваться как изменяемый Строковый объект, который выделяет больше памяти, когда ее содержание изменено.

исходное предложение в вопросе может быть записано еще более ясно и эффективно, заботясь о избыточная запаздывающая запятая :

    StringBuilder result = new StringBuilder();
    for(String string : collectionOfStrings) {
        result.append(string);
        result.append(",");
    }
    return result.length() > 0 ? result.substring(0, result.length() - 1): "";
85
ответ дан Henrik Andersson 24 November 2019 в 05:19
поделиться

Можно быть в состоянии использовать LINQ (для SQL), и можно быть в состоянии использовать Динамический Запрос образец LINQ от MS. http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

0
ответ дан GregUzelac 24 November 2019 в 05:19
поделиться

Я не уверен, насколько "сложный" это, но это, конечно, немного короче. Это будет работать со всевозможными типами набора, например, Set< Integer> List< String> и т.д.

public static final String toSqlList(Collection<?> values) {

    String collectionString = values.toString();

    // Convert the square brackets produced by Collection.toString() to round brackets used by SQL
    return "(" + collectionString.substring(1, collectionString.length() - 1) + ")";
}

Осуществление для читателя : измените этот метод так, чтобы он правильно обработал пустой/пустой набор:)

1
ответ дан Dónal 24 November 2019 в 05:19
поделиться

Просто другой метод для контакта с этой проблемой. Не самое короткое, но это эффективно и сделало задание.

/**
 * Creates a comma-separated list of values from given collection.
 * 
 * @param <T> Value type.
 * @param values Value collection.
 * @return Comma-separated String of values.
 */
public <T> String toParameterList(Collection<T> values) {
   if (values == null || values.isEmpty()) {
      return ""; // Depending on how you want to deal with this case...
   }
   StringBuilder result = new StringBuilder();
   Iterator<T> i = values.iterator();
   result.append(i.next().toString());
   while (i.hasNext()) {
      result.append(",").append(i.next().toString());
   }
   return result.toString();
}
3
ответ дан silverminken 24 November 2019 в 05:19
поделиться

Я думаю, что это не хорошая конструкция идеи sql конкатенация, где значения пункта как Вы делают:

SELECT.... FROM.... WHERE ID IN( value1, value2,....valueN)

, Куда valueX прибывает из списка Строк.

Первый, если Вы сравниваете Строки, они должны быть заключены в кавычки, это, это не тривиально, если Строки могли бы иметь кавычку внутри.

117-секундный, если значения прибывает от пользователя или другой системы, то атака с использованием кода на SQL возможна.

Это является намного более подробным, но что необходимо сделать, создают Строку как это:

SELECT.... FROM.... WHERE ID IN( ?, ?,....?)

и затем связывают переменные с Statement.setString(nParameter,parameterValue).

4
ответ дан 5377037 24 November 2019 в 05:19
поделиться

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

public static <T> String join(Collection<T> values)
{
    StringBuffer ret = new StringBuffer();
    for (T value : values)
    {
        if (ret.length() > 0) ret.append(",");
        ret.append(value);
    }
    return ret.toString();
}

Другое предложение с использованием Collection.toString () короче, но это полагается на Collection.toString () возврат строки в очень определенном формате, на который я лично не хотел бы полагаться.

2
ответ дан Denis Fradlin 24 November 2019 в 05:19
поделиться

Я нашел идиому итератора изящной, потому что она имеет тест для большего количества элементов (опустил пустой/пустой тест для краткости):

public static String convert(List<String> list) {
    String res = "";
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
        res += iterator.next() + (iterator.hasNext() ? "," : "");
    }
    return res;
}
11
ответ дан Miguel Ping 24 November 2019 в 05:19
поделиться

Путем я пишу, что цикл:

StringBuilder buff = new StringBuilder();
String sep = "";
for (String str : strs) {
    buff.append(sep);
    buff.append(str);
    sep = ",";
}
return buff.toString();

не волнуются о производительности сентября. Присвоение очень быстро. Горячая точка имеет тенденцию снимать с первого повторения цикла так или иначе (поскольку это часто должно иметь дело с причудами, такими как пустые и моно/биморфные проверки встраивания).

при использовании его партии (несколько раз) поместите его в общий метод.

существует другой вопрос на stackoverflow контакт с тем, как вставить список идентификаторов в SQL-оператор.

47
ответ дан bluish 24 November 2019 в 05:19
поделиться

Я просто посмотрел на код, который сделал это сегодня. Это - изменение на ответе AviewAnew.

collectionOfStrings = /* source string collection */;
String csList = StringUtils.join(collectionOfStrings.toArray(), ",");

StringUtils (< - commons.lang 2.x, или commons.lang 3.x ссылка ) мы использовали, от Apache палата общин .

74
ответ дан Ogre Psalm33 24 November 2019 в 05:19
поделиться

Используйте метод Google Guava API join :

Joiner.on(",").join(collectionOfStrings);
88
ответ дан Paul Bellora 24 November 2019 в 05:19
поделиться

Вы можете попробовать

List collections = Arrays.asList(34, 26, "...", 2);
String asString = collection.toString();
// justValues = "34, 26, ..., 2"
String justValues = asString.substring(1, asString.length()-1);
5
ответ дан 24 November 2019 в 05:19
поделиться

Что делает код некрасивым, так это особая обработка первого случая. Большинство строк в этом небольшом фрагменте посвящены не выполнению рутинной работы кода, а обработке этого особого случая. И это то, что решают альтернативы, такие как gimel's, перемещая специальную обработку за пределы цикла. Есть один особый случай (ну, вы можете рассматривать и начало, и конец как особые случаи, но только один из них требует особой обработки), поэтому обработка его внутри цикла излишне усложняется.

1
ответ дан 24 November 2019 в 05:19
поделиться

Есть много ручных решений для этого, но я хотел повторить и обновить ответ Джули выше. Используйте класс объединения коллекций google .

Joiner.on(", ").join(34, 26, ..., 2)

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

8
ответ дан 24 November 2019 в 05:19
поделиться

Я только что проверил - в тесте для моей библиотеки Dollar :

@Test
public void join() {
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    String string = $(list).join(",");
}

Это создает беглый обертку вокруг списков / массивов / строки / и т. Д. только один статический импорт : $ .

NB :

Использование диапазонов. Предыдущий список можно повторно написано как $ (1, 5) .join (",")

1
ответ дан 24 November 2019 в 05:19
поделиться

Объединить "методы" можно в массивах и классах, которые расширяют AbstractCollections, но не переопределяют toString() (как практически все коллекции в java.util).

Например:

String s= java.util.Arrays.toString(collectionOfStrings.toArray());
s = s.substing(1, s.length()-1);// [] are guaranteed to be there

Это довольно странный способ, т.к. он работает только для чисел, похожих на SQL-данные.

1
ответ дан 24 November 2019 в 05:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: