Упростить цикл [закрытый]

Каков будет ваш предпочтительный тип цикла для такого случая:

StringBuilder sb = new StringBuilder();
for(Integer id : idList) {
    sb.append("?,");
}

Вкратце: в зависимости от размера списка я хочу добавить материал в String. В приведенном выше примере выдается предупреждение «неиспользуемая переменная».

Я думаю об этих альтернативах:

for(int i=0; i<idList.size(); i++) {
    // ...
}

Мне не нравится все лишнее написание там ...

Iterator it = idList.iterator();
while(it.hasNext()) {
    // ...
    it.next();
}

Сам контур цикла выглядит неплохо, но в итоге я набираю много дополнительного кода (получаю итератор, переходя к следующему элементу ...)

То, что я хотел бы сделать, будет примерно таким:

for(idList) {
    // ...
}

Есть ли лучший стиль /Какой лучший стиль для такого цикла?

8 голосов | спросил reinhard.codes 23 J0000006Europe/Moscow 2011, 13:19:49

5 ответов


15

Я бы использовал обычный метод повторения строк:

String s = repeat("?,", idList.size());

К сожалению, Java не имеет такого метода в стандартном API. Поэтому вы можете написать один:

String repeat(String s, count i) {
  StringBuilder sb = new StringBuilder();
  while (i-- > 0) {
     ab.append(s);
  }
  return sb.toString();
}

или использовать один, предоставленный несколькими стандартными API-интерфейсами надстройки, такими как Apache Commons ' StringUtils.repeat()

ответил RoToRa 23 J0000006Europe/Moscow 2011, 14:19:45
6

Второй пример, безусловно, самый ясный в выражении вашего намерения. Вы хотите сделать что-то несколько раз, в этом случае idList.size().

for( int i = 0; i < idList.size(); ++i ) {
    // ...
}

В третьем вы в основном просто пишете то, что уже генерирует первый пример, так что это определенно не улучшение.

У вас есть точка, в которой цикл for является скорее большой конструкцией кода, которая выражает просто выполнение куска кода в несколько раз. Ruby's times , производится именно для этой цели. На других языках существуют некоторые конструкции кода, которые могут вам помочь. Методы расширения в C # позволяют создать аналогичный оператор, как оператор times Ruby.

Для Java я не верю, что возможен более сжатый синтаксис, поскольку закрытия по умолчанию не поддерживаются в Java.


Как в ответе RoToRa , простой String Вспомогательный класс, содержащий функцию Repeat, скорее всего, самый чистый решение для вас. Он не предоставляет функции для повторения любого типа или операции, но он обеспечивает сжатый синтаксис, который вы ищете.

ответил Steven Jeuris 23 J0000006Europe/Moscow 2011, 14:16:45
4

Я предлагаю использовать Strings.repeat () из библиотеки Google Guava:

String result = Strings.repeat("?,", idList.size());
ответил php-coder 23 J0000006Europe/Moscow 2011, 15:53:22
1

Я бы пошел с первой альтернативой и использовал @SuppressWarnings.

Если вам нужен этот шаблон чаще, как насчет объектно-ориентированного решения:

public static class Repeat<T> implements Iterable<T> {
    private final T[] ts;
    private final int n;

    public Repeat(int n, T ... ts) {
        this.ts = ts;
        this.n = n;
    }

    public Iterator<T> iterator() {
        return new Iterator<T>() {
            int count = 0;   

            public boolean hasNext() {
                return count < n;
            }

            public T next() {
                if (! hasNext()) {
                    throw new NoSuchElementException();
                }
                return ts[(count++) % ts.length];
            }

            public void remove() {
                throw new UnsupportedOperationException("Not supported yet.");
            }

        };
    }
    public static <U> Repeat<U> repeat(int n, U ... us) {
        return new Repeat<U>(n, us);
    }
}

//usage
import static blabla.Repeat.*;
...
for(String s : repeat(idList.size(), "?,")) {
   sb.append(s);
}
ответил Landei 23 J0000006Europe/Moscow 2011, 14:04:42
1

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

Я думаю, что я бы также создал локальный кеш size(), чтобы вы могли избежать вызова функции на каждой итерации цикла , Но это компромисс между скоростью, размером списка, читабельностью и изменением размера списка во время цикла.

int size = idList.size();
for (int i = 0; i < size; ++i) {...}

Если это сильно называемый внутренний цикл, сэкономить несколько десятков тысяч вызовов функций, чтобы вернуть «константу», можно сэкономить некоторое время. Но если вы сделаете что-то подобное, может быть стоит сказать, почему вы сделали это «по-другому» с нормальным ожидаемым способом.

Мне нравится петли, потому что они очень самодостаточны; вы получаете начальное значение, конечное условие и операцию увеличения в одной строке, тогда как цикл while требует поиска для «++» где-то в течение блокировать себя.

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

ответил fwgx 24 J0000006Europe/Moscow 2011, 15:02:34

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132