当我需要在内部类中设置布尔标志时,我的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中更好的模式吗?
答案 0 :(得分:6)
使用 AtomicBoolean 。
以下是有关此问题的热门StackOverflow问题:Why are only final variables accessible in anonymous class?
答案 1 :(得分:3)
在某些情况下,这是最好的模式。
当我找到匹配项时,我建议的唯一改进是return false
。
答案 2 :(得分:3)
如何拥有一个持有任何类型对象的通用持有者类。在您的情况下,它可以保持Boolean
类型。类似的东西:
class Holder<T> {
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<Boolean> boolHolder = new Holder<Boolean>(Boolean.TRUE);
new Runnable() {
@Override
public void run() {
boolHolder.setGenericObj(Boolean.FALSE);
}
};
}
}
当然,这有一些常见的问题,这些问题发生在跨线程共享的可变对象中,但你明白了。此外,对于内存需求紧张的应用程序,如果您对此类方法进行大量调用,则可能会在进行优化时将其划掉。此外,使用AtomicReference
交换/设置引用应该从多个线程使用,尽管跨线程使用它仍然有点可疑。
答案 3 :(得分:1)
一个问题是TIntIntHashMap没有fold/reduce方法,所以你必须使用foreach来模拟它。您可以尝试编写自己的类,扩展TIntIntHashMap,添加reduce方法。
其他解决方案是将TIntProcedure扩展为具有值。类似的东西:
abstract class TIntProcedureWithValue<T> implements TIntProcedure {
private T accumulator;
public T getValue() {return accumulator;}
}
然后你可以将这个类的实例传递给foreach,设置内部累加器而不是外部标志数组,然后获取结果值。
答案 4 :(得分:1)
我不熟悉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中应该提供更简洁的语法。)
答案 5 :(得分:0)
也许是这样的? (实现或扩展......不幸的是,我不知道什么是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;