Java:在两个布尔值(false,true)上循环

18
这是一个风格问题。我想用一个变量on循环两次,第一次为false,第二次为true。哪个更清晰:

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) 其他事项


编辑:不经意的解释下的墨菲定律出现了… 我最初查看的用例是这样的,而不是基于布尔标志做某些事情:

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

但是我认为我喜欢 Brendan 的答案,我会将循环内容重构为一个单独的方法:

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

我猜你不小心回答了自己的问题,而我只是帮助你意识到了这一点? - Brendan Long
我的个人偏好是:for (boolean option : Arrays.asList(false, true)) - Alexander Pozdneev
6个回答

25

因为它只有两行,所以我会跳过循环并执行:

doStuffBasedOnABooleanFlag(false);
doStuffBasedOnABooleanFlag(true);

更少的代码,更明显,更高效。


我更喜欢这个答案。简单明了,不可能产生歧义。 - Joshua
我喜欢那个。for, final, i = 0 while <2 with i == 1?!? 还有任何复杂的东西都太复杂了。只需调用方法两次!:) 我不得不删除我的答案,因为我从太过粗略地看问题中弄错了。两个简单的方法调用更容易阅读。 - stmax
我一开始把顺序搞错了,但已经修正了 (false then true)。谢谢 stmax。 - Brendan Long
我也喜欢这个。我的真实代码没有两个方法调用,它包括大约5行的内容,其中包括一个匿名内部类,我不想重复两次。由于某种原因,我错过了明显的重构成方法调用,并使用循环执行的方法。 - Jason S
作为一个天生的“复杂化者”,这个排名第一的消息真是让我开心! - undefined

13

另一个选项是避免使用布尔值,而是使用枚举类型:

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

你随后可以迭代:

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

或直接调用:

doStuff(Mode.APPEND);
doStuff(Mode.REPLACE);
这样做的好处是API更清晰地指示了正在发生的事情。

1
太棒了。你甚至可能会把之前在循环中的代码放到Mode类本身中,Mode.APPEND.doStuff()。否则,doStuff将是一个非面向对象的实用方法--糟糕。 - Bill K
@Bill K:我同意,但在我的情况下,doStuff()是一个需要访问其他非静态方法的非静态方法。 - Jason S
枚举方法可以是非静态的,并且可以访问枚举内部的其他项。它们非常强大。事实上,枚举是完整功能的类,只限于预定义的实例。 - Bill K

4
如果你真的想使用循环,我会选择(a)。虽然它是新颖的,但它也很清晰高效。我可能会将布尔数组移动到一个私有静态变量中,以避免每次重新创建数组。
但我更喜欢Brendan的答案。

1

可以直接在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

这不是最清晰的方法,所以我不会使用这种方法,除非它在某种内部循环中被执行了大量次数。

我不认为这种方式比(A)或(B)更*清晰。但它是一个不需要分配的单行循环。所以对某些人可能会有用。顺便说一下,从风格上讲,我认为(B)是最好的方式,因为了解其他编程语言的Java新手可能会理解它。 - Adam Gawne-Cain

0

更加高级的循环:

IntStream.range(0, 2).forEach(x -> {
    boolean flag = x == 0;
    doStuffBasedOnABooleanFlag(flag);
});

0

这不仅仅是循环的问题,我对这种使用布尔值的方式也感到非常不舒服。

那么使用类似以下的方式如何:

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

这仍然留下了监听器中的布尔值,但是如果不知道doStuffLater方法的具体功能,我们就无法再深入探讨了。


我需要布尔值。我不能发布我的真实代码,它比这更复杂,而且我有两个UI组件列表,一个以一种方式处理,另一个以另一种方式处理。 - Jason S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接