Есть ли способ определить, повторяется ли цикл в последний раз. Мой код выглядит примерно так:
int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
for(int i : array)
{
builder.append("" + i);
if(!lastiteration)
builder.append(",");
}
Дело в том, что я не хочу добавлять запятую на последней итерации. Теперь есть способ определить, является ли это последней итерацией, или я застрял в цикле for или с помощью внешнего счетчика для отслеживания.
java
for-loop
foreach
conditional-execution
Меркурий
источник
источник
Ответы:
Другой вариант - добавить запятую перед добавлением i, но не на первой итерации. (Пожалуйста, не используйте
"" + i
, кстати, конкатенацию здесь не нужно, а StringBuilder имеет отличную перегрузку append (int).)int[] array = {1, 2, 3...}; StringBuilder builder = new StringBuilder(); for (int i : array) { if (builder.length() != 0) { builder.append(","); } builder.append(i); }
Приятно то, что он будет работать с любым
Iterable
- вы не всегда можете индексировать вещи. («Добавьте запятую, а затем удалите ее в конце» - это хороший совет, когда вы действительно используете StringBuilder, но он не работает для таких вещей, как запись в потоки. Хотя, возможно, это лучший подход для этой точной проблемы. )источник
isFirst
логический флаг. Бонус: тоже быстрее.Другой способ сделать это:
String delim = ""; for (int i : ints) { sb.append(delim).append(i); delim = ","; }
Обновление: для Java 8 теперь у вас есть сборщики
источник
Может быть проще всегда добавлять. А затем, когда вы закончите цикл, просто удалите последний символ. Тоже на тонну меньше условных выражений.
Вы можете использовать
StringBuilder
«SdeleteCharAt(int index)
с индексом бытияlength() - 1
источник
Возможно, вы используете неправильный инструмент для работы.
Это больше руководство, чем то, что вы делаете, но это более элегантно, если не немного "старой школы"
StringBuffer buffer = new StringBuffer(); Iterator iter = s.iterator(); while (iter.hasNext()) { buffer.append(iter.next()); if (iter.hasNext()) { buffer.append(delimiter); } }
источник
Это почти повторение вопроса на StackOverflow . Вам нужно StringUtils и вызвать метод соединения .
StringUtils.join(strArr, ',');
источник
Другое решение (пожалуй, самое эффективное)
int[] array = {1, 2, 3}; StringBuilder builder = new StringBuilder(); if (array.length != 0) { builder.append(array[0]); for (int i = 1; i < array.length; i++ ) { builder.append(","); builder.append(array[i]); } }
источник
Сделайте это простым и используйте стандартный цикл for:
for(int i = 0 ; i < array.length ; i ++ ){ builder.append(array[i]); if( i != array.length - 1 ){ builder.append(','); } }
или просто используйте apache commons-lang StringUtils.join ()
источник
Явные циклы всегда работают лучше, чем неявные.
builder.append( "" + array[0] ); for( int i = 1; i != array.length; i += 1 ) { builder.append( ", " + array[i] ); }
Вы должны заключить все это в оператор if на тот случай, если вы имеете дело с массивом нулевой длины.
источник
Если преобразовать его в классический цикл индекса, да.
Или вы можете просто удалить последнюю запятую после того, как это будет сделано. Вот так:
int[] array = {1, 2, 3...}; StringBuilder builder = new StringBuilder(); for(int i : array) { builder.append(i + ","); } if(builder.charAt((builder.length() - 1) == ',')) builder.deleteCharAt(builder.length() - 1);
Я просто использую
StringUtils.join()
с обычного языка .источник
Как уже упоминалось в наборе инструментов, в Java 8 теперь есть коллекторы . Вот как будет выглядеть код:
String joined = array.stream().map(Object::toString).collect(Collectors.joining(", "));
Я думаю, что это именно то, что вы ищете, и это шаблон, который вы могли бы использовать для многих других вещей.
источник
Вам нужен разделитель классов .
Separator s = new Separator(", "); for(int i : array) { builder.append(s).append(i); }
Реализация класса
Separator
проста. Он обертывает строку, которая возвращается при каждом вызове,toString()
кроме первого вызова, который возвращает пустую строку.источник
На основе java.util.AbstractCollection.toString () он завершает работу раньше, чтобы избежать использования разделителя.
StringBuffer buffer = new StringBuffer(); Iterator iter = s.iterator(); for (;;) { buffer.append(iter.next()); if (! iter.hasNext()) break; buffer.append(delimiter); }
Это эффективно и элегантно, но не так очевидно, как некоторые другие ответы.
источник
(! i.hasNext())
это является важной частью надежности общего подхода. (Другие решения здесь изящно обрабатывают пустые коллекции, так что и вам тоже! :)Вот решение:
int[] array = {1, 2, 3...}; StringBuilder builder = new StringBuilder(); bool firstiteration=true; for(int i : array) { if(!firstiteration) builder.append(","); builder.append("" + i); firstiteration=false; }
Ищите первую итерацию :)
источник
Еще один вариант.
StringBuilder builder = new StringBuilder(); for(int i : array) builder.append(',').append(i); String text = builder.toString(); if (text.startsWith(",")) text=text.substring(1);
источник
Многие из описанных здесь решений немного чрезмерны, ИМХО, особенно те, которые полагаются на внешние библиотеки. Есть хорошая чистая, ясная идиома для создания списка, разделенного запятыми, который я всегда использовал. Он основан на условном операторе (?):
Изменить : исходное решение правильное, но неоптимальное согласно комментариям. Пробуем второй раз:
int[] array = {1, 2, 3}; StringBuilder builder = new StringBuilder(); for (int i = 0 ; i < array.length; i++) builder.append(i == 0 ? "" : ",").append(array[i]);
Вот и все, 4 строки кода, включая объявление массива и StringBuilder.
источник
Вот тест SSCCE, который я запустил (связанный с тем, что мне пришлось реализовать) со следующими результатами:
elapsed time with checks at every iteration: 12055(ms) elapsed time with deletion at the end: 11977(ms)
На моем примере , по крайней мере, пропустив проверку на каждой итерации не заметно быстрее , особенно для здравомыслящих объемов данных, но это быстрее.
import java.util.ArrayList; import java.util.List; public class TestCommas { public static String GetUrlsIn(int aProjectID, List<String> aUrls, boolean aPreferChecks) { if (aPreferChecks) { StringBuffer sql = new StringBuffer("select * from mytable_" + aProjectID + " WHERE hash IN "); StringBuffer inHashes = new StringBuffer("("); StringBuffer inURLs = new StringBuffer("("); if (aUrls.size() > 0) { for (String url : aUrls) { if (inHashes.length() > 0) { inHashes.append(","); inURLs.append(","); } inHashes.append(url.hashCode()); inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"");//.append(","); } } inHashes.append(")"); inURLs.append(")"); return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString(); } else { StringBuffer sql = new StringBuffer("select * from mytable" + aProjectID + " WHERE hash IN "); StringBuffer inHashes = new StringBuffer("("); StringBuffer inURLs = new StringBuffer("("); if (aUrls.size() > 0) { for (String url : aUrls) { inHashes.append(url.hashCode()).append(","); inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"").append(","); } } inHashes.deleteCharAt(inHashes.length()-1); inURLs.deleteCharAt(inURLs.length()-1); inHashes.append(")"); inURLs.append(")"); return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString(); } } public static void main(String[] args) { List<String> urls = new ArrayList<String>(); for (int i = 0; i < 10000; i++) { urls.add("http://www.google.com/" + System.currentTimeMillis()); urls.add("http://www.yahoo.com/" + System.currentTimeMillis()); urls.add("http://www.bing.com/" + System.currentTimeMillis()); } long startTime = System.currentTimeMillis(); for (int i = 0; i < 300; i++) { GetUrlsIn(5, urls, true); } long endTime = System.currentTimeMillis(); System.out.println("elapsed time with checks at every iteration: " + (endTime-startTime) + "(ms)"); startTime = System.currentTimeMillis(); for (int i = 0; i < 300; i++) { GetUrlsIn(5, urls, false); } endTime = System.currentTimeMillis(); System.out.println("elapsed time with deletion at the end: " + (endTime-startTime) + "(ms)"); } }
источник
Другой подход - сохранить длину массива (если имеется) в отдельной переменной (что более эффективно, чем повторная проверка длины каждый раз). Затем вы можете сравнить свой индекс с этой длиной, чтобы определить, добавлять ли последнюю запятую.
РЕДАКТИРОВАТЬ: Еще одним соображением является взвешивание затрат на производительность удаления последнего символа (что может привести к копированию строки) по сравнению с проверкой условного выражения на каждой итерации.
источник
Если вы просто превращаете массив в массив с разделителями-запятыми, во многих языках есть функция соединения именно для этого. Он превращает массив в строку с разделителем между каждым элементом.
источник
В этом случае действительно нет необходимости знать, последнее ли это повторение. Есть много способов решить эту проблему. Один из способов:
String del = null; for(int i : array) { if (del != null) builder.append(del); else del = ","; builder.append(i); }
источник
Здесь есть два альтернативных пути:
1. Строковые утилиты Apache Commons
2: Оставить логическое значение
first
на уровне true. На каждой итерации, еслиfirst
ложно, добавляйте запятую; после этого установитеfirst
значение false.источник
Поскольку это фиксированный массив, было бы проще просто избежать расширенного for ... Если объект является коллекцией, итератор будет проще.
int nums[] = getNumbersArray(); StringBuilder builder = new StringBuilder(); // non enhanced version for(int i = 0; i < nums.length; i++){ builder.append(nums[i]); if(i < nums.length - 1){ builder.append(","); } } //using iterator Iterator<int> numIter = Arrays.asList(nums).iterator(); while(numIter.hasNext()){ int num = numIter.next(); builder.append(num); if(numIter.hasNext()){ builder.append(","); } }
источник