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

私は gnu.trove に精通していませんが、一般的には「アルゴリズム」関数をより具体的にして、ここにコードを少なくする方がよいでしょう。

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 に答える
1

1 つの問題は、TIntIntHashMap にfold/reduceメソッドがないため、foreach を使用してシミュレートする必要があることです。reduce メソッドを追加して TIntIntHashMap を拡張する独自のクラスを作成してみてください。

他の解決策は、TIntProcedure を値を持つように拡張することです。何かのようなもの:

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

次に、このクラスのインスタンスを foreach に渡し、外部フラグ配列の代わりに内部アキュムレータを設定し、後で結果の値を取得できます。

于 2012-07-01T10:00:13.950 に答える
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 に答える