ページ

2014年3月13日

javaのEnumSet

とあるところで書いたものの転載 

EnumSetは、ビット集合を扱っていないとよくわかってもらえないんじゃないかと思ってるんですが、EnumSetについてのお話です。
Cの世代のビット演算大好きなおっさんの話は書かないので、そっちは自分で調べてください。それから、メモリの話もしないです。

それから、これを読むときはカービーダンスの樫木先生のしゃべり方を思い出しながら読んでね。

-----------------

さて、コードの中を見ていると、こんな感じでbooleanで設定のon/offを制御しているところが沢山あるんだよ。

class MySomeClass {
    private boolean opt_1 = false;
    private boolean opt_2 = false;
    private boolean opt_3 = false;
    private boolean opt_4 = false;
     :
}

多分、コードを書いている人はこんなの沢山見ているはずだよ。前回のenumの場合、オプションでとりうる値が複数あって、その中の一個を指定できるってことだったんだよね。でも、今回みたいに、booleanで複数のオプションがあって、その組み合わせがある場合、enumだけだと制御できないよね。

で、そんな組み合わせを簡単に扱えるようにするのがEnumSetなんだ。って言っても、わかんないよね。
コードで見ていったほうがいいかな。

オプション関係は一つのまとまりなので、まとまりはまとまりとしてわかりやすくしたいよね。で、enumでオプション関係をきり出しちゃいます。

class MySomeClass {
   static enum MyOpt { opt_1, opt_2, opt_3, opt4 };
}

それで、実際の値を保持する部分はEnumSetに指定するよ。

class MySomeClass {
   public static enum MyOpt { opt_1, opt_2, opt_3, opt_4 };
   private EnumSet opt = EnumSet.noneOf(MyOpt.class);
}

こんな感じで、4つあったオプションのフィールドが一個にまとまっちゃいました。
実際に使うときは、普通のSetと同じように扱えるよ。

  opt.add(MyOpt.opt_1)

って感じでオプションをセットできるよ。

  opt.contains(MyOpt.opt_2)

のようにして、値がセットされているかどうか判定できるよ。使うときにbooleanそのものよりもちょっと面倒だけどね。

値を削除するのはremoveだよ。


もうちょっと別の使い方は、メソッドの引数がbooleanの羅列で動作を変える場合だよね。
こんなメソッド、気がついたらよくできちゃっているのよね。

public void func(boolean opt1, boolean opt2, boolean opt3, boolean opt4) {
   :
}

で、さらに今回opt5が必要になった・・・。悪夢だよ。そんなら

public void func(EnumSet opt) {
   :
}

ほら、スッキリした。使う方は、メソッドのマニュアルを見ながら、オプションの意味を確認していたのが、enumの値を見ればオプションの意味をしることができるよ。
最後に呼び出し元を見てみよう。

func(true, false, false, true);

  ↓

func(EnumSet,of(MyOpt.opt1, MyOpt.opt4));

どっちが分かりやすい?




うーん、やっぱりビットのお話から入ったほうが良かった?

0 件のコメント: