AVA-11:列挙


11列挙型



11.1列挙


列挙型は簡単に言えば定数セットである.また、これらの列挙型は他の言語でも見つけやすい.またjavaのenumには以下の特徴と利点があります.
  • Javaでは、enumはclassのように使用できます(enum type)
  • タイプ-セキュリティ演算
  • enumで作成、フィールド変数、およびメソッド
  • スイッチドア、
  • を使いやすい
  • 列挙値は
  • 巡回可能である
  • 他のインタフェースは、
  • を実装することができる.

    定義11.1.1 enum

    public enum Day {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
        THURSDAY, FRIDAY, SATURDAY 
    }
    Enumを定義する方法は、上記の形式が最も基本的な方法です.次に、以下に示すように、他の場所で使用できます.
    public class EnumTest {
        Day day;
        
        public EnumTest(Day day) {
            this.day = day;
        }
        
        public void tellItLikeItIs() {
            switch (day) {
                case MONDAY:
                    System.out.println("Mondays are bad.");
                    break;
                        
                case FRIDAY:
                    System.out.println("Fridays are better.");
                    break;
                             
                case SATURDAY: case SUNDAY:
                    System.out.println("Weekends are best.");
                    break;
                            
                default:
                    System.out.println("Midweek days are so-so.");
                    break;
            }
        }
        
        public static void main(String[] args) {
            EnumTest firstDay = new EnumTest(Day.MONDAY);
            firstDay.tellItLikeItIs();
            EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
            thirdDay.tellItLikeItIs();
            EnumTest fifthDay = new EnumTest(Day.FRIDAY);
            fifthDay.tellItLikeItIs();
            EnumTest sixthDay = new EnumTest(Day.SATURDAY);
            sixthDay.tellItLikeItIs();
            EnumTest seventhDay = new EnumTest(Day.SUNDAY);
            seventhDay.tellItLikeItIs();
        }
    }
    以上の結果を以下に示します.
    Mondays are bad.
    Midweek days are so-so.
    Fridays are better.
    Weekends are best.
    Weekends are best.
    しかし,我々が以前確認したenum特徴では,enumはフィールド,構造関数,および方法を定義した.これを確認するために、勤務時間と給与を列挙して計算する例があります.
    class Solution {
        public enum WorkSchedule{
            CLEANING(10,7),
            WASHING(7,8);
    
            private final int time;
            private final int wage;
    
            WorkSchedule(int hour, int wage) {
                this.time = hour;
                this.wage = wage;
            }
    
            public int rest(int hours){
                return this.time - hours;
            }
        }
    
        public static void main(String args[]) {
            WorkSchedule clean = WorkSchedule.CLEANING;
            WorkSchedule wash = WorkSchedule.WASHING;
            System.out.println("Cleaning Total Wage : " + clean.time * clean.wage);
            System.out.println("Cleaning -2 hours : " + clean.rest(2) * clean.wage);
            System.out.println("Cleaning Original Time : " + clean.time);
            System.out.println("Washing Total Wage : " + wash.time * wash.wage);
            System.out.println("Washing -3 hours : " + wash.rest(3) * wash.wage);
            System.out.println("Washing Original Time : " + wash.time );
        }
    }
    結果は以下の通りです.
    Cleaning Total Wage : 70
    Cleaning -2 hours : 56
    Cleaning Original Time : 10
    Washing Total Wage : 56
    Washing -3 hours : 32
    Washing Original Time : 7
    ここでenum値がデータが存在するオブジェクトとして使用されることがわかります.その後、enumで定義されたメソッドを外部から呼び出し、内部の値を一定に保ち、条件に基づいて値を計算することができます.以下は注意事項です.
  • enum値が最初に宣言されていない場合、コンパイルエラーが発生し、最後にセミコロン(;)
  • 各enum値は、独立したオブジェクト管理データ
  • として独立したメモリに割り当てる.
  • 新しいキーワードを使用せずにenum Reference
  • を直接使用

    11.1.2 Type-Safety


    以前にenumがクラスのように利用可能であると判断した場合、type-security演算がなぜ使用できるのかを知ることもできます.
    import java.time.MonthDay;
    import java.util.Iterator;
    
    class Solution {
        public enum Wage{
            TEN(10);
            private final int wage;
            Wage(int wage) {
                this.wage = wage;
            }
        }
    
        public enum Time{
            TEN(10);
            private final int time;
            Time(int time) {
                this.time = time;
            }
        }
    
        public static void main(String args[]) {
            System.out.print("is Wage.TEN equal to Time.TEN ? ");
            if(Wage.TEN.equals(Time.TEN))  System.out.println("YES");
            else System.out.println("NO");
    
            System.out.print("is Wage.TEN.wage == Time.TEN.time ? ");
            if(Wage.TEN.wage == Time.TEN.time) System.out.println("YES");
            else System.out.println("NO");
    
            System.out.println("Wage TEN is : " + Wage.TEN.wage);
            System.out.println("Time TEN is : "  + Time.TEN.time);
            System.out.println(Wage.TEN.getClass());
            System.out.println(Time.TEN.getClass());
        }
    }
    以上の結果は以下の通りです.
    is Wage.TEN equal to Time.TEN ? NO
    is Wage.TEN.wage == Time.TEN.time ? YES
    Wage TEN is : 10
    Time TEN is : 10
    class Solution$Wage
    class Solution$Time
    enumタイプが異なる場合、enum値の文字は同じですが、equals()演算では異なる値が表示されます.

    11.2利用enum


    11.2.1 java.lang.Enum


    Javaではenum実装インタフェースが可能である.逆に、内部ではjavaです.lang.Enumを継承しており、他のクラスを拡張できません.しかし、それを継承しているので、3つの方法を使用することができます.
  • 値():enumタイプの配列
  • を返します.
  • valueOf(String name):nameに対応するenum値を検索し、ない場合は例外
  • が発生します.
  • シーケンス数():enumシーケンス
  • を返します.

    11.2.2 enumタイプ配列、値()


    以前に述べたenumの特徴の一つは巡回可能である.このため、values()というメソッドを使用してenum値を配列に戻します.
    class Solution {
        
        ...
        
        public static void main(String args[]) {
            WorkSchedule clean = WorkSchedule.CLEANING;
            WorkSchedule wash = WorkSchedule.WASHING;
    
            // values() 의 enum 타입 배열을 활용한 순회
            for(WorkSchedule work : WorkSchedule.values()) {
                System.out.println(work + " " + work.ordinal());
            }
        }
    }
    values()を使用するコードが追加され、前の例と同じenumが表示され、巡回されます.その結果は以下の通りである.
    CLEANING 0
    WASHING 1
    CLEANINGとWASHINGは、enumに値を入力する順番で表示されます.また,シーケンス()の手法を用いて入力の順序を確認することも可能である.

    11.2.3ナビゲーションenum値、valueOf()


    次に、検索する値がenumに存在する場合、その値のvalueSOF()を返す例を示します.
    class Solution {
    
        ...
    
        public static void main(String args[]) {
            WorkSchedule clean = WorkSchedule.CLEANING;
            WorkSchedule wash = WorkSchedule.WASHING;
    
            System.out.println(WorkSchedule.valueOf("CLEANING"));
            System.out.println(WorkSchedule.valueOf("DRYING"));
    
        }
    }
    検索する値が存在しない場合、IllegalArgumentException例外が放出されるので、例外処理を行う必要があります.次は結果です.
    CLEANING
    Exception in thread "main" java.lang.IllegalArgumentException: No enum constant Solution.WorkSchedule.DRYING
    	at java.base/java.lang.Enum.valueOf(Enum.java:240)
    	at Solution$WorkSchedule.valueOf(Solution.java:5)
    	at Solution.main(Solution.java:27)
    

    11.3 EnumSet


    最後にEnumSetのまとめです.EnumSetはSetインタフェースを実装する抽象クラスである.次にその例を示します.
  • of():Enum値をEnumSetに追加できます.
  • 「終了タイプ」(Enum Type):完全な値をEnumSetに追加できます.
  • import java.util.EnumSet;
    import java.util.Set;
    
    class Solution {
        public enum Wage {
            ONE(1),
            TWO(2),
            THREE(3),
            FOUR(4),
            FIVE(5);
            private final int wage;
            Wage(int wage) {
                this.wage = wage;
            }
        }
    
    
        public static void main(String args[]) {
            Set<Wage> set1 = EnumSet.of(Wage.FIVE,Wage.THREE);
            EnumSet<Wage> set2 = EnumSet.allOf(Wage.class);
            
            System.out.println(set1);
            System.out.println(set2);
            
        }
    }
    結果は以下の通りです.
    [THREE, FIVE]
    [ONE, TWO, THREE, FOUR, FIVE]
    EnumSetは、必要な演算時に使用するためにenum値のセットを作成することができる.