bitフラグとはなんぞや
もう詳しい人が書いてくれてるので以下のリンクを見てください。
ビット演算によるフラグ管理
ゲームのフラグ管理はビット演算で効率かつ簡単に管理する
何の話がしたいのか
- 一つの変数で
- 排他でない複数のフラグをまとめて管理する
話をしたい。
あとはコードで
int
// 定義.
// 書き方は自由だけどシフト演算で書くと次に定義する値が一目で分かる.
final static int COM_LOLI = 1 << 0;
final static int COM_MOM = 1 << 1;
final static int COM_SIS = 1 << 2;
/**
* next flag:0x0008
* <p>
* AndroidFrameworkで見かけたコメントの書き方.
* 次に定義する値をこうやって書いておくとイケメン.
*/
// 作成.
int flags = COM_LOLI | COM_SIS;
// フラグを立てる.
flags |= COM_MOM;
// フラグを下ろす.
flags &= ~COM_SIS;
// フラグをチェックする.
boolean isOn = (flags & COM_LOLI) != 0;
// ログ出力の際はせめて101010...の形式で出す.
Integer.toBinaryString(flags);
/**
* ログ出力用のメソッドを作るとメンテナンスめんどくさいがイケメン.
*/
static String decodeFlags(final int flags) {
StringBuilder builder = new StringBuilder();
if ((flags & COM_LOLI) != 0) {
builder.append("LOLI").append(" ");
}
if ((flags & COM_MOM) != 0) {
builder.append("MOM").append(" ");
}
if ((flags & COM_SIS) != 0) {
builder.append("SIS").append(" ");
}
return builder.toString();
}
BitSet
// BitSetなんて代物もある.
BitSet bitSet = new BitSet();
// フラグを立てる.
bitSet.set(2);
// フラグを下ろす.
bitSet.clear(1);
// フラグをチェックする.
boolean isOn = bitSet.get(3);
// でもこれは本格的にビット演算を行うときに使うクラスなので
// フラグとして使うのはちょっと扱いづらい.
// toIntegerとかtoLongとかあったら嬉しかったけど
// クラスの目的である可変長ビット配列を担保できないからないのかも.
EnumSet
/**
* まずenumを定義する.
*/
enum Complex {
LOLI("ぅゎょぅι゛ょっょぃ"),
MOM("ママー!"),
SIS("12人いる!");
public final String cry;
Complex(final String cry) {
this.cry = cry;
}
}
// 作成.
EnumSet<Complex> flags = EnumSet.of(Complex.LOLI, Complex.SIS);
// フラグを立てる.
flags.add(Complex.MOM);
// フラグを下ろす.
flags.remove(Complex.SIS);
// フラグをチェックする.
boolean isOn = flags.contains(Complex.SIS);
// 要素全体でループとか
for (Complex complex : Complex.values()) {
Log.d("allCry", complex.cry);
}
// 現在の要素だけでループとか回せて便利
for (Complex complex : flags) {
Log.d("limitedCry", complex.cry);
}
// 「そのフラグが立っていた場合なにをするのか」という情報を
// 即座に取り出せるのでとても便利
結論
速度とか省メモリとかintでDBにそのまま出し入れしたいとかの理由がない限りはEnumSetを使うべし。
速度に関してはEnumSetも十分早いぜってEffectiveJavaに書いてあった。
あと同じ状態を表すintフラグの定数を いろんなクラス に 別の進数表記で定義 した奴、ゆ゛る゛さ゛ん゛!!