いろいろガンガンいこうぜ。体も大事に

普段はJavaでAndroidアプリ開発しているプログラマーのブログです。

Javaの列挙型について(3)

前回,前々回に引き続き列挙型。


列挙型に組み込まれているいくつかのメソッドを確認。


Month.java

package com.rmstar.enumsample;

public enum Month {
    JANUARY("睦月", "冬"),
    FEBRUARY("如月", "冬"),
    MARCH("弥生", "春"),
    APRIL("卯月", "春"),
    MAY("皐月", "春"),
    JUNE("水無月", "夏"),
    JULY("文月", "夏"),
    AUGUST("葉月", "夏"),
    SEPTEMBER("長月", "秋"),
    OCTOBER("神無月", "秋"),
    NOVEMBER("霜月", "秋"),
    DECEMBER("師走", "冬"), ;

    private final String mOldJapaneseName;
    private final String mSeason;

    private Month(String oldJapaneseName, String season) {
        mOldJapaneseName = oldJapaneseName;
        mSeason = season;
    }

    public String getOldJapaneseName() {
        return mOldJapaneseName;
    }

    public String getSeason() {
        return mSeason;
    }
}

前回に引き続き月を表す列挙型を使います。





すべてのインスタンスを列挙する

    private static void showAll() {
        for (Month month : Month.values()) {
            System.out.println(month.getOldJapaneseName());
        }
    }

いちいちべた書きで,全要素を書く必要はありません。
staticメソッドMonth.values()で,全要素が入った配列を取得出来ます。



文字列と列挙型

列挙型で定義したインスタンスが使えるメソッド。
String name();

Object型で定義されているメソッド
String toString();

System.out.println(Month.JULY.toString());
System.out.println(Month.JULY.name());

実行結果は

JULY
JULY

となっています。

同じですね。
ただし,String name()は,finalがついていてオーバーライド禁止になっています。
String name()の返り値は常に列挙型を定義した際に
列挙した文字列(Monthだったら,JANUARYやDECEMBERなど)になります。

一方で,toString()はオーバーライド可能です。
より読みやすい文字列を表示出来るように自分で再定義することも可能です。
また,ライブラリ中の列挙型の場合,
name()より更に読みやすい名前が帰ってくることもあると思いますので,
デバックで用いるのならば,name()よりtoString()の方を選択する方がいいと思います。

static メソッド valueOf(String)
列挙型を定義する際に列挙した文字列を引数とした場合,
その列挙型のインスタンスを返します。
ちなみに列挙されていない文字列な場合,IllegalArgumentExceptionが投げられます。



compareTo()とordinal()

列挙型は,
Enumは Comparableインターフェースを実装しているので,
compareToメソッドが使えます。

System.out.println(Month.APRIL.compareTo(Month.JULY));
System.out.println(Month.JULY.compareTo(Month.JULY));
System.out.println(Month.JULY.compareTo(Month.APRIL));

実行結果は,以下の通り。

-3
0
3

列挙型を定義する際に,先に定義した要素が先に小さい・先に来るようになっています。


そのため次のように,TreeSetを使えばソートもしてくれます。

Set<Month> monthSet = new TreeSet<Month>();
monthSet.add(Month.DECEMBER);
monthSet.add(Month.JANUARY);
monthSet.add(Month.JULY);
System.out.println(monthSet);

実行結果は,

[JANUARY, JULY, DECEMBER]

となります。


int ordinal() メソッド

System.out.println(Month.JANUARY.ordinal());
System.out.println(Month.JULY.ordinal());
System.out.println(Month.DECEMBER.ordinal());

実行結果は,

0
6
11

となります。

その要素の序数を取得出来ます。
これとEnum.values()を用いて次の要素を取得するメソッドを書きました。

private static Month getNext(Month month) {
    Month[] values = Month.values();
    int index = (month.ordinal() + 1) % values.length;
    return values[index];
}

public static void main(String[] args) {
    System.out.println(getNext(Month.JANUARY));
    System.out.println(getNext(Month.JULY));
    System.out.println(getNext(Month.DECEMBER));
}


実行結果は,

FEBRUARY
AUGUST
JANUARY

となります。


それでは,また会えることを祈りつつ。