1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Item 36: Use EnumSet instead of bit fields

Posted at

36.bitフィールドの替わりにEnumSetを用いるべし

enum型の要素が集合に適用される場合、昔はint enumパターン(Item34)を用いて、各定数に2の何乗かを振り分けていた。

// Bit field enumeration constants - OBSOLETE!
public class Text {
    public static final int STYLE_BOLD          = 1 << 0;  // 1
    public static final int STYLE_ITALIC        = 1 << 1;  // 2
    public static final int STYLE_UNDERLINE     = 1 << 2;  // 4
    public static final int STYLE_STRIKETHROUGH = 1 << 3;  // 8
 // Parameter is bitwise OR of zero or more STYLE_ constants
    public void applyStyles(int styles) { ... }
}

これらにOR演算をかけることによって、いくつかの要素を集合にまとめていた。(bit field)

text.applyStyles(STYLE_BOLD | STYLE_ITALIC);

bit演算によって、結合や交差も実現できるが、この方法はint enum の悪い点をすべて引き継いでいる。

定数の集合を作るにおいては、EnumSet クラスを使うべき。性能はbit fieldで処理する場合と遜色ない。
上記の例をenum、EnumSetを用いたのが以下。

// EnumSet - a modern replacement for bit fields
public class Text {
    public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }
 // Any Set could be passed in, but EnumSet is clearly best
    public void applyStyles(Set<Style> styles) { ... }
}

EnumSet インスタンスを渡す、クライアント側のコードは以下のよう。

text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));

上記のapplyStyles メソッドでは、EnumSet ではなく、Set を引数に取っている。たいていのユーザはEnumSet を渡すであろうが、引数として実装クラスを受け付けるのではなく、インターフェースを受け付けるべき(Item64)という原則にしたがってこうしている。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?