caseStudy: enum

javaEnum = typeSafe

■Introduction
よう↓なstaticなクラス変数を用いるが実は問題ありあり。
------------------------------
  final static int ALPHA = 0;
  final static int BETA = 1;
  final static int GAMMA = 2;
  final static int DELTA = 3;

  int alpha = ALPHA; // 問題なし
  int beta = 1;   // 可だど、BETAかどうかの判断が仕切れない。
  int gamma = 10;  // 文法的には可だが、意図に反する。
/-----------------------------
↑をtypeSafeにするために
定数を表わすためのクラスを使って、各定数はそのオブジェクトにしたのが↓
※ただし、勝手にnewされんようconstructorはprivate。
------------------------------
public class Suit {
  private final String name;

  private Suit(String name) {
    this.name = name;
  }

  public String toString() {
    return name;
  }
 
  public static final Suit CLUBS = new Suit("clubs");
  public static final Suit DIAMONDS = new Suit("diamonds");
  public static final Suit HEARTS = new Suit("hearts");
  public static final Suit SPADES = new Suit("spades");
}
/-----------------------------
↑をシリアライズしたんがenum
------------------------------
  public enum Suit {CLUBS, DIAMONDS, HEARTS, SPADES}
/-----------------------------
↑を使ったのが↓
------------------------------
public class EnumTest {
  enum Suit {CLUBS, DIAMONDS, HEARTS, SPADES}

  public static void main(String[] args) {
    Suit suit = Suit.CLUBS;
    System.out.println("Suit is " + suit);
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
C:JSR201examples>java EnumTest
Suit is CLUBS

C:JSR201examples>
/-----------------------------

■advanced
□書き方
------------------------------
ClassModifier enum Identifier { Arg1, Arg2, Arg3, ..., ArgN }
/-----------------------------
※ClassModifierは、public や static、finalのことで、省略可。
※定数は、カンマ繋ぎで定義。

こんな感じ①↓(比較系)
------------------------------
public class EnumTest {
  enum Suit {CLUBS, DIAMONDS, HEARTS, SPADES}

  public static void main(String[] args) {
    Suit suit = Suit.CLUBS;
    Suit suit2 = Suit.DIAMONDS;

    // 代入
    suit = suit2;
    suit2 = Suit.SPADES;

    // 比較
    if (suit == Suit.HEARTS) {
      System.out.println("Suit is HEARTS");
    } else {
      System.out.println("Suit is NOT HEARTS");
    }

    // equals
    if (suit.equals(Suit.DIAMONDS)) {
      System.out.println("Suit is DIAMONDS");
    } else {
      System.out.println("Suit is NOT DIAMONDS");
    }

    // compareTo
    if (suit.compareTo(Suit.HEARTS) > 0) {
      System.out.println("Suit is bigger than HEATS");
    } else if (suit.compareTo(Suit.HEARTS) < 0) {
      System.out.println("Suit is less than HEATS");
    } else {
      System.out.println("Suit is HEATS");
    }
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
C:JSR201examples>java EnumTest
Suit is NOT HEARTS //比較
Suit is DIAMONDS //equals
Suit is less than HEATS //compareTo
/-----------------------------

次。
こんな感じ②↓(switch文)
------------------------------
public class EnumTest2 {
  public enum Num {ONE, TWO, THREE, FOUR}

  public static void main(String[] args) {
    Num num = Num.ONE;

    switch (num) {
     case ONE:
      System.out.println("One");
      break;
     case TWO:
      System.out.println("Two");
      break;
     case THREE:
      System.out.println("Three");
      break;
     case FOUR:
      System.out.println("Four");
      break;
    }
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
One
/-----------------------------
→延々と if ... else if ... else if ... とつなげんとてもヨイ!

次。
こんな感じ③↓(syso系)
------------------------------
public class EnumTest {
  public enum Num {ONE, TWO, THREE, FOUR}

  public static void main(String[] args) {
    Num num = Num.ONE;

    System.out.println("Num is " + num);
    System.out.println("TWO is " + Num.TWO);
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
Num is ONE
TWO is TOW
/-----------------------------
→compareToができんのに、きちんと文字列が出力される!
 (static final な定数を出力しても int だったら数値しか出力されん)

次。
こんな感じ④↓(拡張for文)
------------------------------
public class EnumTest {
  public enum Num {ONE, TWO, THREE, FOUR}

  public static void main(String[] args) {
    System.out.println("Num.VALUES's Class : " + Num.values().getClass());
    for (Num num : Num.values()) {
      System.out.println("Num is " + num);
    }
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
Num.$VALUES's Class : class [LEnumTest$Num;
Num is ONE
Num is TWO
Num is THREE
Num is FOUR
/-----------------------------
※"[LEnumTest$Num"の"[":配列のこと。
※"[LEnumTest$Num"の"LEnumTest$Num":JNIなどで使用されるシグネチャ。
※"[LEnumTest$Num"の"LEnumTest":クラス名。
※"[LEnumTest$Num"の"$":内部クラスのこと。
※"[LEnumTest$Num"=EnumTestクラスの内部クラスNumの配列 ゆうこと。

ちなみに。
こんな感じ⑤↓(ordinal)
------------------------------
public class EnumTest {
  public enum Num {ONE, TWO, THREE, FOUR}

  public static void main(String[] args) {
    for (Num num : Num.values()) {
      System.out.println("Num[" + num + "]'s ordinal is " + num.ordinal());
    }
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
Num[ONE]'s ordinal is 0
Num[TWO]'s ordinal is 1
Num[THREE]'s ordinal is 2
Num[FOUR]'s ordinal is 3
/-----------------------------

次。
こんな感じ⑥↓(overrideでsyso)
------------------------------
public class EnumTest {
  public enum Num {ONE, TWO, THREE, FOUR;
    public String toString() {
      return name().substring(0,1).toUpperCase()
        + name().substring(1).toLowerCase();
    }
  }

  public static void main(String[] args) {
    for (Num num : Num.values()) {
      System.out.println("Num is " + num);
    }
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
Num is One
Num is Two
Num is Three
Num is Four
/-----------------------------

次。
こんな感じ⑦↓(originalMethod)
------------------------------
public class EnumTest7 {
  public enum Num {ONE, TWO, THREE, FOUR;
    public Num increment() {
      int next = ordinal() + 1;
      return values()[next];
    }
  }

  public static void main(String[] args) {
    for (Num num = Num.ONE; num.compareTo(Num.FOUR) < 0; num = num.increment()) {
      System.out.println("Num is " + num);
    }
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
Num is ONE
Num is TWO
Num is THREE
/-----------------------------

次。
こんな感じ⑧↓(constructor)
------------------------------
public class EnumTest {
  private enum Num {ONE(1), TWO(2), THREE(3), FOUR(4);
    private final int value;

    Num(int value) {
      this.value = value;
    }

    public int getValue() {
      return value;
    }
  }

  public static void main(String[] args) {
    for (Num num: Num.values()) {
      System.out.println(num + " is " + num.getValue());
    }
  }
}
/-----------------------------
↑の実行結果が↓
------------------------------
ONE is 1
TWO is 2
THREE is 3
FOUR is 4
/-----------------------------

次。
こんな感じ⑨↓(State パターン)
(START -> RUNNING -> STOP な状態遷移の実装例)
------------------------------
public class EnumTest9 {
  private enum State {
    START {
      public State nextState() {
        return State.RUNNING;
      }
    },

    RUNNING {
      public State nextState() {
        return State.STOP;
      }
    },

    STOP {
      public State nextState() {
        return State.STOP;
      }
    };

    public abstract State nextState();
  }

  public static void main(String[] args) {
    State state = State.START;
    
    System.out.println("Present State is " + state);
    state = state.nextState();
    System.out.println("Next State is " + state);
    state = state.nextState();
    System.out.println("Last State is " + state);
  }
}
/-----------------------------
※State パターン:状態を表わす派生クラスでふるまいの違うメソッドを定義する必要がある。
↑の実行結果が↓
------------------------------
Present State is START
Next State is RUNNING
Last State is STOP
/-----------------------------

次。
こんな感じ⑩↓(interfaceをimplement)
------------------------------
import java.util.Iterator;

public class EnumTest10 {
  private enum Num implements Iterable {ONE, TWO, THREE, FOUR;
    public Iterator iterator() {
      return new Iterator() {
        private int position = 0;

        public boolean hasNext() {
          return position < Num.values().length;
        }

        public Num next() {
          Num num = Num.values()[position];
          position++;
          
          return num;
        }

        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }
  }

  public static void main(String[] args) {
    Num num = Num.ONE;
    Iterator it = num.iterator();

    while (it.hasNext()) {
      System.out.println(it.next());
    }
  }
}
/-----------------------------

ref:
虎の穴
http://www.javainthebox.net/laboratory/J2SE1.5/LangSpec/TypesafeEnum/TypesafeEnum.html

tag : enum

2008-11-04 23:10 : __lang__java : コメント : 0 : トラックバック : 0 :
コメントの投稿
非公開コメント

« next  ホーム  prev »

search

ad



counter


tag cloud

category cloud