Подтвердить что ты не робот

Обнаружение первой итерации через цикл for-each в Java

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

    StringBuilder builder = new StringBuilder() ;
    boolean firstIterationFlag = true ;

    for ( String s : list ){
        if ( firstIterationFlag) {
            firstIterationFlag = false ;
        } else {
            builder.append(separator);
        }
        builder.append(s) ;         
   }
   return builder.toString() ;

Есть ли способ сделать это без флага?

4b9b3361

Ответ 1

Один простой способ для этой ситуации - отметить, что вы всегда можете добавить пустую строку:

// For the first iteration, use a no-op separator
String currentSeparator = "";
for (String s : list) {
    builder.append(currentSeparator);
    builder.append(s);
    // From the second iteration onwards, use this
    currentSeparator = separator;
}

В качестве альтернативы (и предпочтительно) используйте класс Guava Joiner, чтобы начать с:)

Этот сценарий "столяр" почти всегда является тем, который указан для этого требования, поэтому просто используйте Joiner. Для других сценариев используйте обычный цикл for или используйте условие в соответствии с вашим кодом.

Ответ 2

Не использовать foreach, но с помощью итератора вручную:

Iterator<String> it = list.iterator();
if(it.hasNext()){
    doSomeThingForTheFirstTime(it.next());
    while(it.hasNext()){
        doSomethingElse(it.next);
    }
}

(Кстати, это почти то, что класс класса Guava Joiner делает внутренне, хотя и на более высоком уровне)

Ответ 3

В конкретном случае, который вы цитируете, используйте Guava Joiner вместо того, чтобы перематывать свой собственный...

Объект, который объединяет фрагменты текста (заданные как массив, Iterable, varargs или даже Map) с разделителем. Он либо добавляет результаты в Appendable, либо возвращает их как String. Пример:

Joiner joiner = Joiner.on(separator).skipNulls();
return joiner.join(list);

Ответ 4

Просто для удовольствия здесь другой вариант.

    StringBuilder builder = new StringBuilder();
    for (String s : list) {
        builder.append(separator);
        builder.append(s);
    }
    builder.deleteCharAt(0);
    return builder.toString();

Ответ 5

Решение Java 8

Если у вас есть Java 8, вы можете просто использовать String#join, нет необходимости в Guava:

String.join(", ", list)

Ответ 6

Я бы использовал функцию commons.lang StringUtils.join(см. http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/StringUtils.html). Я настоятельно рекомендую вам познакомиться с этой и другими вспомогательными библиотеками, чтобы избежать повторного создания колеса.

Ответ 7

Вы также можете использовать следующий метод:

public static String toString(List<?> list, String separator) {
    StringBuilder sb = new StringBuilder();
    Iterator<?> it = list.iterator();
    while (it.hasNext()) {
        Object next = it.next();
        sb.append(next);
        if (it.hasNext()) {
            sb.append(separator);
        }
    }
    return sb.toString();
}

Усиленный оператор for эквивалентен базовому выражению for формы:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
    VariableModifiersopt TargetType Identifier =
        (TargetType) #i.next();
    Statement
}

#i - это автоматически сгенерированный идентификатор

Ответ 8

Ну, это не обнаружит первую итерацию в цикле, но решит проблему. Просто добавьте сепаратор в конце каждой строки и отрежьте последний разделитель.

StringBuilder builder = new StringBuilder() ;

for ( String s : list ) {
    builder.append(s) ;         
    builder.append(separator);
}
builder.setLength(builder.length() - separator.length());
return builder.toString() ;

Ответ 9

Вы можете попробовать следующее:)

int i = 0;
for (something : manythings) {
    i++;
}