Тернарный оператор Java и установка значений индекса цикла - PullRequest
3 голосов
/ 23 мая 2011

У меня есть цикл for ArrayList.

Если условие выполняется в цикле for:

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

Случай, когда мы только что удалили последний элемент ArrayList:

i = (i > 0) ? i-- : i;

Моя проблема в том, что приведенное выше не уменьшает i на 1, когда i> 0. Я использовал троичные операторы бесчисленное количество раз, но никогда не видел такого поведения. Я проверил, что я действительно> 0 и что секция i-- вызывается. Это просто не уменьшает ценность i. Снятие проверки значения 0 и простой запуск i--; действительно уменьшают i, как и ожидалось.

EDIT2: Хорошо, кто-то отредактировал мое последнее редактирование, где я упомянул, что я специально НЕ использую ListIterator в этом случае из-за чувствительного к производительности характера самого цикла, находящегося в критической части кода Android.

Ответы [ 8 ]

6 голосов
/ 23 мая 2011

i-- уменьшает i, но возвращает исходное значение.

i = i-- будет уменьшать i, а затем присваивает его исходному значению.

Вы должны использовать i - 1.

4 голосов
/ 23 мая 2011

Наименьшее исправление:

Возможно, вы хотите что-то вроде этого:

for (int i = 0; i < l.size(); i++) {         <--------------------------------.
    if (cond) {                                                               |
        l.remove(i);                                                          |
        i--;              // even if i == -1, it will be set back to 0 here --'
    }
}

Обратная итерация вместо:

Другим распространенным решением является итерация в обратном направлении, например:

for (int i = l.size() - 1; i >= 0; i--) {
    if (cond) {
        l.remove(i);
    }
}

Использование ListIterator (если не критично для производительности):

Тем не менее, вы еще лучше с ListIterator:

Iterator<String> iter = l.iterator();
while (iter.hasNext()) {
    if (shouldRemove(iter.next())
        iter.remove();
}
3 голосов
/ 23 мая 2011

Вы пробовали?:

i = (i > 0) ? --i : i;

С предварительным декрементом вы должны решить все свои проблемы.

2 голосов
/ 23 мая 2011

Алгоритм, который вы описали, является плохой стратегией для того, что вы пытаетесь сделать: удаление элемента из ArrayList является операцией O (n), поэтому его применение ко всему ArrayList в общем случае равно O (n ^ 2). случай.

Гораздо лучшая стратегия:

  • Создать новый пустой ArrayList
  • Зациклите один раз исходный ArrayList и добавьте только элементы, которые вы хотите сохранить, в новый ArrayList

Это O (n), и на самом деле это будет более простой код (вам не нужно беспокоиться о том, чтобы возиться с границами цикла и т. Д.)

2 голосов
/ 23 мая 2011

Делайте правильно: используйте итератор для циклического перебора списка массивов и безопасного удаления элементов во время итерации.

2 голосов
/ 23 мая 2011

Наличие такого назначения, как i = i-- (что происходит для i > 0), просто не имеет смысла: что именно вы ожидаете здесь? Вместо этого используйте следующее:

i = (i > 0) ? i - 1 : i;

Или, еще лучше:

if (i > 0)
    i--;
1 голос
/ 23 мая 2011

Как уже говорили другие, i-- уменьшает i и возвращает исходное значение, что означает, что ваш код выполнил бы декремент, но затем немедленно вернул его к исходному значению.

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

Было бы лучше просто набрать i-1, что не установит значение i дважды:

i = (i > 0) ? i-1 : i;

Все это говорит о том, что, поскольку ложный вариант троичного числа ничего не делает, вам, вероятно, лучше использовать простое if():

if(i > 0) { i--; }

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

1 голос
/ 23 мая 2011

Не используйте троичный оператор с noop.

если (i> 0) { --я }

точно описывает функциональность, которую вы хотите (на основе вашего примера).

...