java: looping on the two boolean values (false, tr

2020-07-03 05:14发布

问题:

This is a stylistic question. I want to loop twice with a variable on which is set to false, then to true. Which of these is clearer:

A)

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);
}

C) something else


edit: Murphy's law of unintended interpretations comes into play... the use case I have originally looked something like this instead of 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);
      }
   }
}

But I think I like Brendan's answer, I'll just refactor the loop contents into a separate method:

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);
      }
   }
}

回答1:

Since it's two lines, I'd just skip the loop and do:

doStuffBasedOnABooleanFlag(false);
doStuffBasedOnABooleanFlag(true);

Less code, more obvious, more efficient.



回答2:

Another option would be to avoid the boolean and use an enum:

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

You could then either iterate:

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

Or do the calls directly:

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

The advantage of this would be that the API indicates more clearly what's happening.



回答3:

If you really want to use a loop, I would go with (a). While it's novel, it's also clear and efficient. I might move the boolean array to a private static, to avoid recreating the array every time.

But I like Brendan's answer better.



回答4:

It's not just the loop, I'm also really uncomfortable with the use of booleans in this way.

What about something like:

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

That still leaves the boolean within the listener, but without knowing what the doStuffLater method does that's as far as we can go.



回答5:

It can be done directly within a for loop, without creating a new array.

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

Output:

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

This isn't the most clear way, so I wouldn't use this approach unless it were in some kind of inner loop where it would be executed a large number of times.