最终数组的模式而不是内部类中boolean标志的非final变量

当我需要在内部类中设置布尔标志时,我的Java代码经常出现这种情况。 不可能使用原始布尔类型,因为内部类只能使用外部的最终变量,所以我使用这样的模式:

// class from gnu.trove is not of big importance, just to have an example private final TIntIntHashMap team = new TIntIntHashMap(); // ....... code ............ final boolean[] flag = new boolean[]{false}; team.forEachValue(new TIntProcedure() { @Override public boolean execute(int score) { if(score >= VICTORY_SCORE) { flag[0] = true; } return true; // to continue iteration over hash map values } }); // ....... code .............. 

最终数组的模式而不是非最终变量的效果很好,除了它看起来不够漂亮。 有人知道Java中更好的模式吗?

在某些情况下,这是最好的模式。

我能建议的唯一改进是找到匹配后return false

使用AtomicBoolean

这是一个关于这个问题的流行的StackOverflow问题: 为什么在匿名类中只能访问最终变量?

如何拥有一个持有任何类型对象的通用持有者类。 在您的情况下,它可以包含Boolean类型。 就像是:

 class Holder { private T genericObj; public Holder(T genericObj) { this.genericObj = genericObj; } public T getGenericObj() { return genericObj; } public void setGenericObj(T genericObj) { this.genericObj = genericObj; } } 

并将其用作:

 public class Test { public static void main(String[] args) throws Exception { final Holder boolHolder = new Holder(Boolean.TRUE); new Runnable() { @Override public void run() { boolHolder.setGenericObj(Boolean.FALSE); } }; } } 

当然,这具有通过线程共享的可变对象所发生的常见问题,但是您可以理解。 此外,对于内存需求紧张的应用程序,如果您对此类方法进行大量调用,则可能会在进行优化时将其划掉。 此外,使用AtomicReference交换/设置引用应该从多个线程使用,尽管跨线程使用它仍然有点可疑。

一个问题是TIntIntHashMap没有fold / reduce方法,所以你必须使用foreach来模拟它。 您可以尝试编写自己的类,扩展TIntIntHashMap,添加reduce方法。

其他解决方案是仅扩展TIntProcedure以获得值。 就像是:

 abstract class TIntProcedureWithValue implements TIntProcedure { private T accumulator; public T getValue() {return accumulator;} } 

然后,您可以将此类的实例传递给foreach,设置内部累加器而不是外部标志数组,然后获取结果值。

我不熟悉gnu.trove,但通常情况下,“algortihm”函数更具体,在这里留下更少的代码。

 private final IntIntHashMap team = new IntIntHashMap(); boolean found = team.value().containsMatch(new IntPredicate() { public boolean is(int score) { return score >= VICTORY_SCORE; } }); 

(Java SE 8中应该提供更简洁的语法。)

也许是这样的? (实现或扩展……不幸的是,我不知道什么是TIntProcedure):

  class FlagResult implements TIntProcedure { boolean flag = false; @Override public boolean execute(int score) { flag = score >= VICTORY_SCORE; return !flag; } }; FlagResult result = new FlagResult(); team.forEachValue(result); boolean flag = result.flag;