1

当我需要在内部类中设置布尔标志时,我的 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 模式吗?

4

6 回答 6

6

使用AtomicBoolean

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

于 2012-07-01T10:20:39.443 回答
4

拥有一个包含任何类型对象的通用持有者类怎么样。在您的情况下,它可以包含一个 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交换/设置引用应该注意从多个线程中使用,尽管跨线程使用它仍然有点问题。

于 2012-07-01T09:40:48.670 回答
3

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

我可以建议的唯一改进是return false当您找到匹配项时。

于 2012-07-01T09:31:57.593 回答
1

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

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

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

然后你可以将这个类的一个实例传递给foreach,设置内部累加器而不是外部标志数组,然后得到结果值。

于 2012-07-01T10:00:13.950 回答
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 中应该提供更简洁的语法。)

于 2012-07-01T12:38:43.680 回答
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;
于 2012-07-01T10:01:31.130 回答