Последняя итерация расширенного цикла в java

Есть ли способ определить, выполняется ли цикл в последний раз. Мой код выглядит примерно так:

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();

for(int i : array)
{
    builder.append("" + i);
    if(!lastiteration)
        builder.append(",");
}

Теперь я не хочу добавлять запятую в последнюю итерацию. Теперь есть способ определить, является ли это последней итерацией, или я придерживаюсь цикла for или использую внешний счетчик для отслеживания.

Ответ 1

Другой вариант - добавить запятую перед добавлением 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, но это не работает для таких вещей, как запись в потоки. Возможно, это лучший подход для этой точной проблемы. )

Ответ 2

Другой способ сделать это:

String delim = "";
for (int i : ints) {
    sb.append(delim).append(i);
    delim = ",";
}

Обновление: для Java 8 теперь Collectors

Ответ 3

Это может быть проще всегда добавлять. И затем, когда вы закончите свой цикл, просто удалите финальный символ. Тонны меньше условностей тоже.

Вы можете использовать StringBuilder deleteCharAt(int index) с индексом length() - 1

Ответ 4

Возможно, вы используете неправильный инструмент для задания.

Это более ручная работа, чем то, что вы делаете, но это более элегантно, если не немного "старая школа".

 StringBuffer buffer = new StringBuffer();
 Iterator iter = s.iterator();
 while (iter.hasNext()) {
      buffer.append(iter.next());
      if (iter.hasNext()) {
            buffer.append(delimiter);
      }
 }

Ответ 5

Это почти повторение fooobar.com/questions/17835/.... Вы хотите StringUtils и вызвать метод join.

StringUtils.join(strArr, ',');

Ответ 6

Другое решение (возможно, наиболее эффективное)

    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]);
        }
    }

Ответ 7

Явные циклы всегда работают лучше, чем неявные.

builder.append( "" + array[0] );
for( int i = 1; i != array.length; i += 1 ) {
   builder.append( ", " + array[i] );
}

Вы должны обернуть все это в if-statement на всякий случай, если вы имеете дело с массивом нулевой длины.

Ответ 8

держите его простым и используйте стандарт для цикла:

for(int i = 0 ; i < array.length ; i ++ ){
    builder.append(array[i]);
    if( i != array.length - 1 ){
        builder.append(',');
    }
}

или просто используйте apache commons-lang StringUtils.join()

Ответ 9

Если вы преобразуете его в классический индексный цикл, да.

Или вы можете просто удалить последнюю запятую после ее завершения. Например:

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);

Me, я просто использую StringUtils.join() из commons- Ланг.

Ответ 10

Вам нужен Сепаратор класса.

Separator s = new Separator(", ");
for(int i : array)
{
     builder.append(s).append(i);
}

Реализация класса Separator выполняется прямо. Он переносит строку, которая возвращается при каждом вызове toString(), за исключением первого вызова, который возвращает пустую строку.

Ответ 11

На основе java.util.AbstractCollection.toString() он выйдет раньше, чтобы избежать разделителя.

StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
for (;;) {
  buffer.append(iter.next());
  if (! iter.hasNext())
    break;
  buffer.append(delimiter);
}

Это эффективный и элегантный, но не такой само собой разумеющийся, как некоторые другие ответы.

Ответ 12

Вот решение:

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;
}

Ищите первую итерацию:)  

Ответ 13

Еще один вариант.

StringBuilder builder = new StringBuilder();
for(int i : array)
    builder.append(',').append(i);
String text = builder.toString();
if (text.startsWith(",")) text=text.substring(1);

Ответ 14

Многие из описанных здесь решений немного выше, IMHO, особенно те, которые полагаются на внешние библиотеки. Существует хорошая чистая, ясная идиома для достижения списка, разделенного запятыми, которые я всегда использовал. Он полагается на условный (?) Оператор:

Изменить. Исходное решение правильно, но не оптимально в соответствии с комментариями. Повторяя второй раз:

    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.

Ответ 15

Здесь был проведен тест 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)");
  }
}

Ответ 16

В качестве инструментария, упомянутого в Java 8, теперь Collectors. Вот как выглядит код:

String joined = array.stream().map(Object::toString).collect(Collectors.joining(", "));

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

Ответ 17

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

EDIT: Еще одно соображение - это взвешивание стоимости исполнения для удаления конечного символа (что может привести к копированию строки) против того, чтобы на каждой итерации было проверено условие.

Ответ 18

Два альтернативных пути:

1: Apache Commons String Utils

2: сохранить логическое имя first, установить значение true. На каждой итерации, если first является ложным, добавьте запятую; после этого установите first в значение false.

Ответ 19

Если вы только превращаете массив в массив с разделителями-запятыми, на многих языках для этого есть функция соединения. Он превращает массив в строку с разделителем между каждым элементом.

Ответ 20

В этом случае нет необходимости знать, является ли это последним повторением. Есть много способов решить эту проблему. Один из способов:

String del = null;
for(int i : array)
{
    if (del != null)
       builder.append(del);
    else
       del = ",";
    builder.append(i);
}

Ответ 21

С его фиксированным массивом было бы проще просто избежать расширения для... Если Object представляет собой коллекцию, то итератором будет проще.

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(",");
   }
}