IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

Effective Java 読書会 8 日目 「それ enum で出来るよ」

はじめに

ビット演算? それE... - はてなちゃんセリフ - はてなセリフ

今日読んだところ

143 ページ〜 159 ページ

int 定数とか使わない

型安全じゃないから

enum 使う

enum Hoge {
    FOO, BAR;
}

簡単

メソッドも持てる

enum Hoge {
    FOO, BAR;

    void a() {
        /* (snip) */
    }
}

で、以下のように使う

Hoge.FOO.a();

シングルトンも

最近の Java では enum でやるらしい!

switch 文の代わりに固有メソッド

enum Hoge {
    FOO { void a() { /*snip*/ } },
    BAR { void a() { /*snip*/ } };

    abstract void a();
}

以下のコードが

// これはダメ
switch(obj) {
    case Hoge.FOO: /*snip*/ break;
    case Hoge.BAR: /*snip*/ break;
    default: throw new AssertionError();
}

以下で良くなる!

// case の書き忘れもなくて安心!
obj.a();

戦略 enum

enum の値をカテゴライズする

// たとえば
enum Hoge {
    FOO { void a() { /*snip*/ } }, // これと
    BAR { void a() { /*snip*/ } }, // これがまったく同じ処理だったとして
    BAZ { void a() { /*snip*/ } };

    abstract void a();
}

以下のようになる

enum Hoge {
    FOO(Strategy.STRATEGY_1),
    BAR(Strategy.STRATEGY_1),
    BAZ(Strategy.STRATEGY_2);

    private enum Strategy {
        STRATEGY_1 { void a() { /* ... */ } }, STRATEGY_2 { void a() /* ... */ }

        abstract void a();
    }

    // 戦略の委譲
    private final Strategy strategy;
    Hoge(Strategy strategy) { this.strategy = strategy; }
    void a() { strategy.a(); }
}

values 便利

for (Hoge v : Hoge.values()) { /* ... */ }

インスタンスの配列

ordinary は使うのはやめましょう

値が増えるとコンパイルの度に順番変わるので
private で id 的なフィールドを持てと

EnumSet 便利!

64 個までならビット演算(|)と比べても遜色のない速度で動く!テラすごす!!

Set<Hoge> set = EnumSet.of(Hoge.FOO, Hoge.BAR, Hoge.BAZ);  // ビット演算 FOO (=0x1) | BAR (=0x1 << 1) | BAZ (=0x1 << 2) と比べても遜色のない速度で動く

of メソッドかっけー!

EnumMap も便利

Enum の ordinal をインデックスにした配列じゃなく EnumMap を使おう

まとめ

enum すげー便利!めっちゃ使う!