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

Операция для логической переменной "Get and AND" в Java

Возможно ли в Java использовать синтаксис типа (i++, ++i) для логических логических операторов?

У меня есть логическая переменная, которая истинна только для первой итерации цикла foreach. Эта итерация должна быть skipeed.

Полный синтаксис

for (...)
{
    if (bool)
    {
        bool &= false;
        continue;
    }
}

Интересно, есть ли способ сократить синтаксис, не используя AtomicBoolean. Например, конструкция if (bool &= false) является синтаксически правильной, но я думаю, что она сравнит конечный результат, а не исходное значение.

Google не мой друг, потому что поисковый запрос вводит в заблуждение

4b9b3361

Ответ 1

Лично я бы упростил ваш текущий код:

for (...)
{
    if (bool)
    {
        bool = false;
        continue;
    }
    // Rest of code
}

... но если вы действительно хотите сделать это в состоянии if в качестве побочного эффекта, вы можете использовать:

for (...)
{
    if (bool && !(bool = false))
    {
        continue;
    }
    // Rest of code
}

Здесь первый операнд оператора && покрывает последующие операции, а !(bool = false) всегда будет оцениваться до true и устанавливает bool в значение false.

Другой вариант, из комментариев:

for (...)
{
    if (bool | (bool = false))
    {
        continue;
    }
    // Rest of code
}

Это выполняет назначение на каждой итерации, но все равно дает правильный результат каждый раз.

Я действительно, действительно не использовал бы ни один из этих последних двух вариантов.

Ответ 2

Ваш код - обычное дело. Однако есть альтернатива:

for (SomeType thing : Iterables.skip(things, 1)) {
    // process thing
}

Это использует метод Google Guava Iterables.skip() и выдает ожидаемый результат - цикл для каждого цикла, выполняющий итерацию по коллекции и пропускающий первый элемент.

Ответ 3

В качестве альтернативы просто используйте целочисленную переменную и используйте ++ для последующего увеличения.

int iter = 0;
for (...) {
    if (iter++ == 0) {
        continue;
    }
    ...
}

Если вы хотите пропустить первую итерацию, это может быть даже легче понять.

Ответ 4

Не используйте приращения для булевых типов. Если вы должны использовать логическое значение, либо переключите его, например, !bool, либо просто установите для него значение false:

for (...){
    if (bool) {
        bool = false;
        continue;
    }
}

В идеале, если вы хотите только пропустить первую, последнюю или n-ю итерацию, не используйте boolean вообще, а вместо int...

    int skipIndex = 0;
    for(int index=0; index < 5; index++){
        if(index != skipIndex) {
            System.out.println(index);
        }
    }

... или следующие, чтобы пропустить первую итерацию:

    int[] values = new int[]{0, 1, 2, 3, 4};
    for (int index = 1; index < values.length; index++) {
        System.out.println(values[index]);
    }       

Ответ 5

Если (и только если), вы действительно уверены, что вам всегда нужно продолжать первую итерацию, почему бы просто не пропустить эту итерацию? Вместо того, чтобы начинать с i=0, начинайте с

for(i=1....

Ответ 6

Я пытаюсь понять, почему OP пытается использовать bool &= false;, когда, очевидно, будет bool = false. В этом смысле ответ Джона Скита (неудивительно) правильный.

То, что я думаю, что OP действительно хочет сделать, это установить переменную в false и протестировать ее за один шаг. Это причина ссылки на AtomicBoolean. Это ничего не значит делать с петлями. IE он хочет сделать то же самое, что:

int a=0;
for ( ... ) {
    if (a++ == 0 ) { // works if we aren't doing too many iterations
        continue;
    }
    ...
}

то есть. он хочет эквивалент оператора пост-инкремента.

Если я прав, это не тот цикл, о котором он беспокоился, тот факт, что a здесь читается один раз, затем снова читается отдельно.

Это случай преждевременной оптимизации. Компилятор Java очень вероятен (нет, я его не тестировал) для создания одного чтения и тестирования и кода с помощью

boolean a=false;
for ( ... ) {
    if (!a) {
        a = true;
        continue;
    }
}

как предложил Джон Скит.

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

Обратите внимание, что в реальном цикле for вы можете просто:

int i;
boolean skip;
for (i=0, skip=true; i<10; i++, skip=false) {
    if (skip)
        continue;
}

Ответ 7

for (int i = 0, boolean doIt = false; i < 10; i++, doit = true) {
    if (doIt) {
        doStuff();
    }
}