Так как строки неизменны, можно хотеть использовать класс 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): "";
Можно быть в состоянии использовать LINQ (для SQL), и можно быть в состоянии использовать Динамический Запрос образец LINQ от MS. http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Я не уверен, насколько "сложный" это, но это, конечно, немного короче. Это будет работать со всевозможными типами набора, например, 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) + ")";
}
Осуществление для читателя : измените этот метод так, чтобы он правильно обработал пустой/пустой набор:)
Просто другой метод для контакта с этой проблемой. Не самое короткое, но это эффективно и сделало задание.
/**
* 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();
}
Я думаю, что это не хорошая конструкция идеи sql конкатенация, где значения пункта как Вы делают:
SELECT.... FROM.... WHERE ID IN( value1, value2,....valueN)
, Куда valueX
прибывает из списка Строк.
Первый, если Вы сравниваете Строки, они должны быть заключены в кавычки, это, это не тривиально, если Строки могли бы иметь кавычку внутри.
117-секундный, если значения прибывает от пользователя или другой системы, то атака с использованием кода на SQL возможна.
Это является намного более подробным, но что необходимо сделать, создают Строку как это:
SELECT.... FROM.... WHERE ID IN( ?, ?,....?)
и затем связывают переменные с Statement.setString(nParameter,parameterValue)
.
Существуют некоторые сторонние библиотеки 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 () возврат строки в очень определенном формате, на который я лично не хотел бы полагаться.
Я нашел идиому итератора изящной, потому что она имеет тест для большего количества элементов (опустил пустой/пустой тест для краткости):
public static String convert(List<String> list) {
String res = "";
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
res += iterator.next() + (iterator.hasNext() ? "," : "");
}
return res;
}
Путем я пишу, что цикл:
StringBuilder buff = new StringBuilder();
String sep = "";
for (String str : strs) {
buff.append(sep);
buff.append(str);
sep = ",";
}
return buff.toString();
не волнуются о производительности сентября. Присвоение очень быстро. Горячая точка имеет тенденцию снимать с первого повторения цикла так или иначе (поскольку это часто должно иметь дело с причудами, такими как пустые и моно/биморфные проверки встраивания).
при использовании его партии (несколько раз) поместите его в общий метод.
существует другой вопрос на stackoverflow контакт с тем, как вставить список идентификаторов в SQL-оператор.
Я просто посмотрел на код, который сделал это сегодня. Это - изменение на ответе AviewAnew.
collectionOfStrings = /* source string collection */;
String csList = StringUtils.join(collectionOfStrings.toArray(), ",");
StringUtils (< - commons.lang 2.x, или commons.lang 3.x ссылка ) мы использовали, от Apache палата общин .
Используйте метод Google Guava API join
:
Joiner.on(",").join(collectionOfStrings);
Вы можете попробовать
List collections = Arrays.asList(34, 26, "...", 2);
String asString = collection.toString();
// justValues = "34, 26, ..., 2"
String justValues = asString.substring(1, asString.length()-1);
Что делает код некрасивым, так это особая обработка первого случая. Большинство строк в этом небольшом фрагменте посвящены не выполнению рутинной работы кода, а обработке этого особого случая. И это то, что решают альтернативы, такие как gimel's, перемещая специальную обработку за пределы цикла. Есть один особый случай (ну, вы можете рассматривать и начало, и конец как особые случаи, но только один из них требует особой обработки), поэтому обработка его внутри цикла излишне усложняется.
Есть много ручных решений для этого, но я хотел повторить и обновить ответ Джули выше. Используйте класс объединения коллекций google .
Joiner.on(", ").join(34, 26, ..., 2)
Он обрабатывает аргументы переменных, итерации и массивы и правильно обрабатывает разделители более чем одного символа (в отличие от ответа Гиммеля). Он также будет обрабатывать нулевые значения в вашем списке, если вам это нужно.
Я только что проверил - в тесте для моей библиотеки Dollar :
@Test
public void join() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
String string = $(list).join(",");
}
Это создает беглый обертку вокруг списков / массивов / строки / и т. Д. только один статический импорт : $
.
NB :
Использование диапазонов. Предыдущий список можно повторно написано как $ (1, 5) .join (",")
Объединить "методы" можно в массивах и классах, которые расширяют 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-данные.