Java: зацикливание на двух логических значениях (false, true) - PullRequest
14 голосов
/ 05 марта 2010

Это стилистический вопрос. Я хочу дважды выполнить цикл с переменной on, для которой установлено значение false, затем значение true. Что из этого понятнее:

А)

for (final boolean on : new boolean[] { false, true} )
{
   doStuffBasedOnABooleanFlag(on);
}

B)

for (int i = 0; i < 2; ++i)
{
   final boolean on = (i == 1);
   doStuffBasedOnABooleanFlag(on);
}

в) что-то еще


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

for (final boolean on : new boolean[] { false, true} )
{
   JButton button = on ? onButton : offButton;
   button.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent event) {
      doStuffLaterBasedOnABooleanFlag(on);
      }
   }
}

Но я думаю, что мне нравится ответ Брендана, я просто сделаю рефакторинг содержимого цикла в отдельный метод:

doStuffBasedOnABooleanFlag(false);
doStuffBasedOnABooleanFlag(true);

   ...

private void doStuffBasedOnABooleanFlag(final boolean on)
{
   JButton button = on ? onButton : offButton;
   button.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent event) {
      doStuffLaterBasedOnABooleanFlag(on);
      }
   }
}

Ответы [ 5 ]

23 голосов
/ 05 марта 2010

Поскольку это две строки, я просто пропущу цикл и сделаю:

doStuffBasedOnABooleanFlag(false);
doStuffBasedOnABooleanFlag(true);

Меньше кода, более очевидно, более эффективно.

11 голосов
/ 05 марта 2010

Другой вариант - избежать логического значения и использовать перечисление:

enum Mode { APPEND, REPLACE } // or whatever your boolean indicated

Затем можно выполнить итерацию:

for(Mode m : Mode.values()) doStuff(m);

или выполнить вызовы напрямую:

doStuff(Mode.APPEND);
doStuff(Mode.REPLACE);

Преимущество этого состоит в том, что API более четко показывает, что происходит.

3 голосов
/ 05 марта 2010

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

Но мне больше нравится ответ Брендана.

0 голосов
/ 10 октября 2018

Это можно сделать непосредственно в цикле for, не создавая массив new.

for (boolean on=false, done=false; !done; done=on, on=true) {
    System.out.println("on="+on+", done="+done);
}

Выход:

on=false, done=false
on=true, done=false

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

0 голосов
/ 05 марта 2010

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

Как насчет чего-то вроде:

  ActionListener myListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent event) {
      doStuffLaterBasedOnABooleanFlag(event.getSource() == onButton);
    }
  };
  onButton.addActionListener(myListener);
  offButton.addActionListener(myListener);

Это по-прежнему оставляет логическое значение внутри слушателя, но не зная, что делает метод doStuffLater, это все, что мы можем сделать.

...