Последняя итерация улучшена для цикла в Java - PullRequest
131 голосов
/ 13 ноября 2008

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

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

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

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

Ответы [ 21 ]

3 голосов
/ 21 марта 2009

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

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

Это эффективно и элегантно, но не так очевидно, как некоторые другие ответы.

2 голосов
/ 13 ноября 2008

Вот решение:

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

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

1 голос
/ 11 ноября 2016

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

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

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

1 голос
/ 01 августа 2014

Вот тест 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)");
  }
}
1 голос
/ 21 марта 2009

Многие из описанных здесь решений, 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]); 

Итак, в четырех строках кода, включая объявление массива и StringBuilder.

1 голос
/ 21 марта 2009

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

StringBuilder builder = new StringBuilder();
for(int i : array)
    builder.append(',').append(i);
String text = builder.toString();
if (text.startsWith(",")) text=text.substring(1);
0 голосов
/ 15 июня 2017

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

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(",");
   }
}
0 голосов
/ 24 мая 2011

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

String del = null;
for(int i : array)
{
    if (del != null)
       builder.append(del);
    else
       del = ",";
    builder.append(i);
}
0 голосов
/ 13 ноября 2008

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

РЕДАКТИРОВАТЬ: Еще одним соображением является взвешивание затрат производительности на удаление окончательного символа (что может привести к копированию строки) с проверкой условной проверки на каждой итерации.

0 голосов
/ 13 ноября 2008

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

...