Java Language
列挙型
サーチ…
前書き
enum
キーワードを使用して宣言されています)は、単一クラスの大量の定数の簡略構文です。
構文
- [public / protected / private] enum Enum_name {//新しい列挙型を宣言します。
- ENUM_CONSTANT_1 [、ENUM_CONSTANT_2 ...]; // enum定数を宣言します。これは列挙型の内部の最初の行でなければならず、末尾にセミコロンを付けてカンマで区切る必要があります。
- ENUM_CONSTANT_1(param)[、ENUM_CONSTANT_2(param)...]; //パラメータでenum定数を宣言します。パラメータ型はコンストラクタと一致する必要があります。
- ENUM_CONSTANT_1 {...} [、ENUM_CONSTANT_2 {...} ...]; //オーバーライドされたメソッドで列挙型定数を宣言します。 enumに抽象メソッドが含まれている場合は、これを行う必要があります。そのような方法はすべて実装されなければならない。
- ENUM_CONSTANT.name()// enum定数の名前のStringを返します。
- ENUM_CONSTANT.ordinal()//この列挙定数の序数を返します。その列挙定数の位置は、初期定数にゼロの序数が代入されます。
- Enum_name.values()//呼び出されるたびにその列挙型のすべての定数を含む新しい配列(Enum_name []型)を返します。
- Enum_name.valueOf( "ENUM_CONSTANT")// ENUM_CONSTANT.name()の逆数 - 与えられた名前の列挙定数を返します。
- Enum.valueOf(Enum_name.class、 "ENUM_CONSTANT")//前のものと同義語:ENUM_CONSTANT.name()の逆数 - 与えられた名前の列挙定数を返します。
備考
制限事項
列挙型は常にjava.lang.Enum
を拡張しているため、クラスを拡張する列挙型は不可能です。ただし、多くのインターフェイスを実装できます。
ヒントとコツ
彼らの特殊な表現のために、enumをキーとして使用できるより効率的なマップとセットがあります。これらは、非専門のカウンターパートよりも頻繁に速く実行されます。
宣言と基本列挙型の使用
Enumは、一連の定数を定義するためにコンパイル時に知られている何回かだけインスタンス化される密封クラスの構文シュガーと考えることができます。
さまざまな季節を列挙する簡単な列挙は、次のように宣言されます。
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
列挙型定数は必ずしも大文字である必要はありませんが、定数の名前は完全に大文字で、単語はアンダースコアで区切られています。
Enumを独自のファイルに宣言できます:
/**
* This enum is declared in the Season.java file.
*/
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
しかし、別のクラスの中で宣言することもできます:
public class Day {
private Season season;
public String getSeason() {
return season.name();
}
public void setSeason(String season) {
this.season = Season.valueOf(season);
}
/**
* This enum is declared inside the Day.java file and
* cannot be accessed outside because it's declared as private.
*/
private enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
最後に、メソッド本体またはコンストラクタ内でEnumを宣言することはできません。
public class Day {
/**
* Constructor
*/
public Day() {
// Illegal. Compilation error
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
public void aSimpleMethod() {
// Legal. You can declare a primitive (or an Object) inside a method. Compile!
int primitiveInt = 42;
// Illegal. Compilation error.
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
Season season = Season.SPRING;
}
}
重複する列挙定数は使用できません:
public enum Season {
WINTER,
WINTER, //Compile Time Error : Duplicate Constants
SPRING,
SUMMER,
FALL
}
enumのすべての定数は、デフォルトでpublic
、 static
およびfinal
です。すべての定数はstatic
ので、列挙型の名前を使用して直接アクセスできます。
列挙型定数は、メソッドパラメータとして渡すことができます:
public static void display(Season s) {
System.out.println(s.name()); // name() is a built-in method that gets the exact name of the enum constant
}
display(Season.WINTER); // Prints out "WINTER"
values()
メソッドを使用して、列挙定数の配列を取得できます。値は、返される配列の宣言順になることが保証されています。
Season[] seasons = Season.values();
注:このメソッドは、呼び出されるたびに新しい値の配列を割り当てます。
列挙定数を反復するには:
public static void enumIterate() {
for (Season s : Season.values()) {
System.out.println(s.name());
}
}
switch
文でenumを使用できます。
public static void enumSwitchExample(Season s) {
switch(s) {
case WINTER:
System.out.println("It's pretty cold");
break;
case SPRING:
System.out.println("It's warming up");
break;
case SUMMER:
System.out.println("It's pretty hot");
break;
case FALL:
System.out.println("It's cooling down");
break;
}
}
==
を使用してenum定数を比較することもできます。
Season.FALL == Season.WINTER // false
Season.SPRING == Season.SPRING // true
列挙型定数を比較するもう1つの方法は、次のように落とし穴に簡単に入ることができるので、悪い習慣とみなされる以下のようにequals()
を使うことです:
Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error
内のインスタンスの集合がまた、 enum
実行時に変更することができない他のクラスと同様に、ので、インスタンス自体が本質的に不変でないenum
以下に示されているように可変フィールドを含むことができます。
public enum MutableExample {
A,
B;
private int count = 0;
public void increment() {
count++;
}
public void print() {
System.out.println("The count of " + name() + " is " + count);
}
}
// Usage:
MutableExample.A.print(); // Outputs 0
MutableExample.A.increment();
MutableExample.A.print(); // Outputs 1 -- we've changed a field
MutableExample.B.print(); // Outputs 0 -- another instance remains unchanged
しかし、良い例は、 enum
インスタンスを不変にすることです。つまり、追加のフィールドを持たない場合や、すべてのフィールドがfinal
とマークされていて不変の場合です。これにより、アプリケーションの存続期間中、 enum
はメモリをリークさせず、すべてのスレッドにわたってそのインスタンスを使用することが安全であることを保証します。
Enum
クラスは以下のことを行うため、 Enum
型は暗黙的にSerializable
とComparable
実装します。
public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable
コンストラクタを持つ列挙型
enum
はpublicコンストラクタを持つことはできません。ただし、privateコンストラクタは受け入れられます(enumのコンストラクタはデフォルトでpackage-privateです)。
public enum Coin {
PENNY(1), NICKEL(5), DIME(10), QUARTER(25); // usual names for US coins
// note that the above parentheses and the constructor arguments match
private int value;
Coin(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
int p = Coin.NICKEL.getValue(); // the int value will be 5
列挙型のインスタンスは限られているので、すべてのフィールドを非公開にしてゲッターメソッドを提供することをお勧めします。
Enum
をclass
として実装する場合、次のようになります。
public class Coin<T extends Coin<T>> implements Comparable<T>, Serializable{
public static final Coin PENNY = new Coin(1);
public static final Coin NICKEL = new Coin(5);
public static final Coin DIME = new Coin(10);
public static final Coin QUARTER = new Coin(25);
private int value;
private Coin(int value){
this.value = value;
}
public int getValue() {
return value;
}
}
int p = Coin.NICKEL.getValue(); // the int value will be 5
Enum定数は技術的に変更可能であるため、enum定数の内部構造を変更するためにsetterを追加することができます。しかし、これは非常に悪い習慣と考えられ、避けるべきです。
ベストプラクティスは、Enumフィールドをfinal
不変にすることです。
public enum Coin {
PENNY(1), NICKEL(5), DIME(10), QUARTER(25);
private final int value;
Coin(int value){
this.value = value;
}
...
}
同じ列挙型で複数のコンストラクタを定義することができます。あなたがするとき、あなたのenum宣言で渡す引数は、呼び出されるコンストラクタを決定します:
public enum Coin {
PENNY(1, true), NICKEL(5, false), DIME(10), QUARTER(25);
private final int value;
private final boolean isCopperColored;
Coin(int value){
this(value, false);
}
Coin(int value, boolean isCopperColored){
this.value = value;
this.isCopperColored = isCopperColored;
}
...
}
注: Enum
クラスはSerializable
を実装する必要があります。
メソッドとスタティックブロックの使用
列挙型には、すべてのクラスと同様に、メソッドを含めることができます。これがどのように動作するかを確認するために、次のようなenumを宣言します:
public enum Direction {
NORTH, SOUTH, EAST, WEST;
}
列挙型を逆方向に返すメソッドを用意しましょう:
public enum Direction {
NORTH, SOUTH, EAST, WEST;
public Direction getOpposite(){
switch (this){
case NORTH:
return SOUTH;
case SOUTH:
return NORTH;
case WEST:
return EAST;
case EAST:
return WEST;
default: //This will never happen
return null;
}
}
}
これは、フィールドと静的イニシャライザブロックを使用することでさらに改善できます。
public enum Direction {
NORTH, SOUTH, EAST, WEST;
private Direction opposite;
public Direction getOpposite(){
return opposite;
}
static {
NORTH.opposite = SOUTH;
SOUTH.opposite = NORTH;
WEST.opposite = EAST;
EAST.opposite = WEST;
}
}
この例では、反対方向をプライベートインスタンスフィールドに格納されているopposite
静的初めて初期化され、 Direction
使用されます。 (ので、この特定のケースではNORTH
参照SOUTH
と逆に)、我々が使用することはできませんコンストラクタを持つ列挙型 (ここでコンストラクタNORTH(SOUTH), SOUTH(NORTH), EAST(WEST), WEST(EAST)
よりエレガントになるとできるようになりopposite
しますfinal
に宣言されるが、自己参照となり、したがって許可されない)。
インターフェースを実装する
これは、プリコンパイルされた正規表現パターンに対してString
入力をテストする呼び出し可能な関数でもあるenum
です。
import java.util.function.Predicate;
import java.util.regex.Pattern;
enum RegEx implements Predicate<String> {
UPPER("[A-Z]+"), LOWER("[a-z]+"), NUMERIC("[+-]?[0-9]+");
private final Pattern pattern;
private RegEx(final String pattern) {
this.pattern = Pattern.compile(pattern);
}
@Override
public boolean test(final String input) {
return this.pattern.matcher(input).matches();
}
}
public class Main {
public static void main(String[] args) {
System.out.println(RegEx.UPPER.test("ABC"));
System.out.println(RegEx.LOWER.test("abc"));
System.out.println(RegEx.NUMERIC.test("+111"));
}
}
列挙型の各メンバーは、このメソッドを実装することもできます。
import java.util.function.Predicate;
enum Acceptor implements Predicate<String> {
NULL {
@Override
public boolean test(String s) { return s == null; }
},
EMPTY {
@Override
public boolean test(String s) { return s.equals(""); }
},
NULL_OR_EMPTY {
@Override
public boolean test(String s) { return NULL.test(s) || EMPTY.test(s); }
};
}
public class Main {
public static void main(String[] args) {
System.out.println(Acceptor.NULL.test(null)); // true
System.out.println(Acceptor.EMPTY.test("")); // true
System.out.println(Acceptor.NULL_OR_EMPTY.test(" ")); // false
}
}
列挙型多型パターン
この方法は、の「拡張可能な」セット受け入れる必要がある場合enum
値を、プログラマは、通常の上のような多型を適用することができるclass
ここanywere使用されるインタフェース作成することにより、 enum
Sを使用しなければならないが。
public interface ExtensibleEnum {
String name();
}
このようにして、インタフェースによってタグ付け(実装)されたenum
パラメータとして使用することができ、プログラマはメソッドによって受け入れられる可変量のenum
型を作成することができます。これは、例えば、デフォルトの(変更不可能な) enum
があるAPIにおいて有用であり、これらのAPIのユーザは、より多くの値でenum
を「拡張」したい。
デフォルトのenum値のセットは、次のように定義できます。
public enum DefaultValues implements ExtensibleEnum {
VALUE_ONE, VALUE_TWO;
}
追加の値は次のように定義できます。
public enum ExtendedValues implements ExtensibleEnum {
VALUE_THREE, VALUE_FOUR;
}
enum
型の使用方法を示すサンプル - printEnum()
が両方のenum
型の値を受け入れる方法に注意してください:
private void printEnum(ExtensibleEnum val) {
System.out.println(val.name());
}
printEnum(DefaultValues.VALUE_ONE); // VALUE_ONE
printEnum(DefaultValues.VALUE_TWO); // VALUE_TWO
printEnum(ExtendedValues.VALUE_THREE); // VALUE_THREE
printEnum(ExtendedValues.VALUE_FOUR); // VALUE_FOUR
注:このパターンは、別の列挙型で既に1つの列挙型で定義されている列挙型値を再定義することを妨げるものではありません。これらの列挙型の値は別のインスタンスになります。また、switch-on-enumを使用することはできません。これは、実際のenum
ではなくインターフェースであるからです。
抽象メソッドを持つ列挙型
列挙型は抽象メソッドを定義することができ、それぞれのenum
メンバーは実装する必要があります。
enum Action {
DODGE {
public boolean execute(Player player) {
return player.isAttacking();
}
},
ATTACK {
public boolean execute(Player player) {
return player.hasWeapon();
}
},
JUMP {
public boolean execute(Player player) {
return player.getCoordinates().equals(new Coordinates(0, 0));
}
};
public abstract boolean execute(Player player);
}
これにより、各enumメンバは、最上位定義のメソッドの型をオンにすることなく、指定された操作に対して独自の動作を定義できます。
このパターンは、多態性および/またはインターフェイスの実装を使用して通常達成されるものの短い形式です。
enumを文書化する
必ずしもenum
名が理解できるほど明確ではない。 enum
を文書化するには、標準のjavadocを使用します。
/**
* United States coins
*/
public enum Coins {
/**
* One-cent coin, commonly known as a penny,
* is a unit of currency equaling one-hundredth
* of a United States dollar
*/
PENNY(1),
/**
* A nickel is a five-cent coin equaling
* five-hundredth of a United States dollar
*/
NICKEL(5),
/**
* The dime is a ten-cent coin refers to
* one tenth of a United States dollar
*/
DIME(10),
/**
* The quarter is a US coin worth 25 cents,
* one-fourth of a United States dollar
*/
QUARTER(25);
private int value;
Coins(int value){
this.value = value;
}
public int getValue(){
return value;
}
}
列挙型の値を取得する
各enumクラスには、 values()
という名前の暗黙の静的メソッドが含まれていvalues()
。このメソッドは、そのenumのすべての値を含む配列を返します。このメソッドを使用して値を反復処理することができます。ただし、このメソッドは呼び出されるたびに新しい配列を返すことに注意することが重要です。
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
/**
* Print out all the values in this enum.
*/
public static void printAllDays() {
for(Day day : Day.values()) {
System.out.println(day.name());
}
}
}
Set
が必要な場合は、 EnumSet.allOf(Day.class)
も使用できます。
境界型パラメータとしての列挙型
ジェネリックのクラスをjavaに書くときには、typeパラメータがenumであることを保証することができます。すべての列挙型はEnum
クラスを拡張するので、次の構文を使用できます。
public class Holder<T extends Enum<T>> {
public final T value;
public Holder(T init) {
this.value = init;
}
}
この例では、型T
は列挙型でなければなりません 。
名前で定数を取得する
enum DayOfWeek
があるとしDayOfWeek
:
enum DayOfWeek {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}
enumは組み込みの静的なvalueOf()
メソッドでコンパイルされます。このメソッドは名前で定数を検索するために使用できます:
String dayName = DayOfWeek.SUNDAY.name();
assert dayName.equals("SUNDAY");
DayOfWeek day = DayOfWeek.valueOf(dayName);
assert day == DayOfWeek.SUNDAY;
これは、動的列挙型を使用しても可能です。
Class<DayOfWeek> enumType = DayOfWeek.class;
DayOfWeek day = Enum.valueOf(enumType, "SUNDAY");
assert day == DayOfWeek.SUNDAY;
指定されたenumに一致する名前の定数がない場合、これらのvalueOf()
メソッドはどちらもIllegalArgumentException
をスローします。
Guavaライブラリは、明示的な例外処理を排除するためにGuava Optional
を返すヘルパーメソッドEnums.getIfPresent()
を提供します。
DayOfWeek defaultDay = DayOfWeek.SUNDAY;
DayOfWeek day = Enums.valueOf(DayOfWeek.class, "INVALID").or(defaultDay);
assert day == DayOfWeek.SUNDAY;
単一要素列挙型でシングルトンパターンを実装する
列挙型定数は、列挙型が初めて参照されるときにインスタンス化されます。したがって、単一要素の列挙型でSingletonソフトウェア設計パターンを実装することができます。
public enum Attendant {
INSTANCE;
private Attendant() {
// perform some initialization routine
}
public void sayHello() {
System.out.println("Hello!");
}
}
public class Main {
public static void main(String... args) {
Attendant.INSTANCE.sayHello();// instantiated at this point
}
}
Joshua Blochの "Effective Java"の本によれば、単一要素列挙型がシングルトンを実装する最良の方法です。このアプローチには以下の利点があります。
- スレッドの安全性
- 単一インスタンス化の保証
- すぐに使えるシリアル化
また、 インタフェースを実装するセクションに示すように、このシングルトンは1つ以上のインタフェースを実装することもできます。
プロパティ(フィールド)を持つ列挙型
私たちは、定数値だけでなく、より多くの情報でenum
を使いたい場合、2つの列挙型を比較できるようにしたいと考えています。
次の例を考えてみましょう。
public enum Coin {
PENNY(1), NICKEL(5), DIME(10), QUARTER(25);
private final int value;
Coin(int value){
this.value = value;
}
public boolean isGreaterThan(Coin other){
return this.value > other.value;
}
}
ここでは、その値を表すCoin
というEnum
を定義しました。 isGreaterThan
メソッドを使用すると、2つのenum
isGreaterThan
を比較できます。
Coin penny = Coin.PENNY;
Coin dime = Coin.DIME;
System.out.println(penny.isGreaterThan(dime)); // prints: false
System.out.println(dime.isGreaterThan(penny)); // prints: true
列挙型を文字列に変換する
列挙型をStringに変換する場合は、2つの方法があります。
我々が持っていると仮定:
public enum Fruit {
APPLE, ORANGE, STRAWBERRY, BANANA, LEMON, GRAPE_FRUIT;
}
では、 Fruit.APPLE
ようなものをどうすれば"APPLE"
変換できますか?
name()
を使用して変換するname()
name()
はenum
内部メソッドであり、 enum
のString
表現を返します。戻りString
は、enum値がどのように定義されたかを正確に表します。
例えば:
System.out.println(Fruit.BANANA.name()); // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.name()); // "GRAPE_FRUIT"
toString()
を使用して変換する
toString()
は、 デフォルトでは、 name()
と同じ動作をするようにオーバーライドされています 。
しかし、 toString()
は開発者によってオーバーライドされ、ユーザーフレンドリなString
印刷しやすくなります
あなたのコードをチェックしたいなら、
toString()
使わないでくださいtoString()
name()
はもっと安定しています。値をログや標準出力などに出力するときにのみtoString()
使用します
デフォルトでは:
System.out.println(Fruit.BANANA.toString()); // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "GRAPE_FRUIT"
上書きされる例
System.out.println(Fruit.BANANA.toString()); // "Banana"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "Grape Fruit"
Enum定数の特定のボディ
enum
特定の定数の具体的な動作を定義することが可能であるenum
のデフォルトの動作オーバーライドenum
、この技術は、 一定の特定体として知られています。
John、Ben、Lukeの3人のピアノの生徒がPianoClass
という名前のenum
PianoClass
で次のように定義されているとします。
enum PianoClass {
JOHN, BEN, LUKE;
public String getSex() {
return "Male";
}
public String getLevel() {
return "Beginner";
}
}
そして1日2人の他の生徒、リタとトムがセックス(女性)とレベル(中級)で、以前のものと一致しない:
enum PianoClass2 {
JOHN, BEN, LUKE, RITA, TOM;
public String getSex() {
return "Male"; // issue, Rita is a female
}
public String getLevel() {
return "Beginner"; // issue, Tom is an intermediate student
}
}
次のように、単に新しい宣言を定数宣言に追加するのは正しいとは限りません。
PianoClass2 tom = PianoClass2.TOM;
PianoClass2 rita = PianoClass2.RITA;
System.out.println(tom.getLevel()); // prints Beginner -> wrong Tom's not a beginner
System.out.println(rita.getSex()); // prints Male -> wrong Rita's not a male
PianoClass2
デフォルトの動作を次のようにオーバーライドする定数RitaとTomのそれぞれの動作を定義することができます:
enum PianoClass3 {
JOHN, BEN, LUKE,
RITA {
@Override
public String getSex() {
return "Female";
}
},
TOM {
@Override
public String getLevel() {
return "Intermediate";
}
};
public String getSex() {
return "Male";
}
public String getLevel() {
return "Beginner";
}
}
トムのレベルとリタのセックスは、次のようになります。
PianoClass3 tom = PianoClass3.TOM;
PianoClass3 rita = PianoClass3.RITA;
System.out.println(tom.getLevel()); // prints Intermediate
System.out.println(rita.getSex()); // prints Female
コンテンツ固有のボディを定義する別の方法は、コンストラクタを使用することです。
enum Friend {
MAT("Male"),
JOHN("Male"),
JANE("Female");
private String gender;
Friend(String gender) {
this.gender = gender;
}
public String getGender() {
return this.gender;
}
}
および使用法:
Friend mat = Friend.MAT;
Friend john = Friend.JOHN;
Friend jane = Friend.JANE;
System.out.println(mat.getGender()); // Male
System.out.println(john.getGender()); // Male
System.out.println(jane.getGender()); // Female
ゼロインスタンスの列挙型
enum Util {
/* No instances */;
public static int clamp(int min, int max, int i) {
return Math.min(Math.max(i, min), max);
}
// other utility methods...
}
シングルトン (1インスタンスクラス)にenum
を使用できるように、ユーティリティクラス(0インスタンスクラス)に使用できます。 enum定数の(空の)リストを必ず終了させてください;
。
非公開のコンストラクタと比較して、プロと議論の議論のためのインスタンス化を防ぐためのゼロインスタンスの列挙型とプライベートなコンストラクタの質問を参照してください。
静的フィールドを持つ列挙型
enumクラスに静的フィールドが必要な場合は、enum値自体の後に作成されることに注意してください。つまり、次のコードではNullPointerException
ます。
enum Example {
ONE(1), TWO(2);
static Map<String, Integer> integers = new HashMap<>();
private Example(int value) {
integers.put(this.name(), value);
}
}
これを修正する方法は次のとおりです。
enum Example {
ONE(1), TWO(2);
static Map<String, Integer> integers;
private Example(int value) {
putValue(this.name(), value);
}
private static void putValue(String name, int value) {
if (integers == null)
integers = new HashMap<>();
integers.put(name, value);
}
}
静的フィールドを初期化しないでください:
enum Example {
ONE(1), TWO(2);
// after initialisisation integers is null!!
static Map<String, Integer> integers = null;
private Example(int value) {
putValue(this.name(), value);
}
private static void putValue(String name, int value) {
if (integers == null)
integers = new HashMap<>();
integers.put(name, value);
}
// !!this may lead to null poiner exception!!
public int getValue(){
return (Example.integers.get(this.name()));
}
}
初期化:
- 列挙型の値を作成する
- 副作用として、putValue()が呼び出され、整数が初期化されます
- 静的な値が設定されます。
- 整数=ヌル; //列挙型の後に実行されるので、整数の内容は失われます
Enum値の比較とインクルード
Enumは定数のみを含み、 ==
と直接比較できます。したがって、参照チェックのみが必要で、 .equals
メソッドを使用する必要はありません。さらに、 .equals
が正しく使用されていない場合、 NullPointerException
する可能性がありますが、これは==
checkの場合には==
ません。
enum Day {
GOOD, AVERAGE, WORST;
}
public class Test {
public static void main(String[] args) {
Day day = null;
if (day.equals(Day.GOOD)) {//NullPointerException!
System.out.println("Good Day!");
}
if (day == Day.GOOD) {//Always use == to compare enum
System.out.println("Good Day!");
}
}
}
EnumSet
クラスをグループ化、補完、範囲指定するには、異なるメソッドを含むEnumSet
クラスがあります。
EnumSet#range
:2つのエンドポイントで定義された範囲でenumのサブセットを取得するEnumSet#of
:範囲を持たない特定のenumのセット。複数of
メソッドがオーバーロードされています。EnumSet#complementOf
:メソッドのパラメータで提供されるenum値を補完するenumのセットenum Page { A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 } public class Test { public static void main(String[] args) { EnumSet<Page> range = EnumSet.range(Page.A1, Page.A5); if (range.contains(Page.A4)) { System.out.println("Range contains A4"); } EnumSet<Page> of = EnumSet.of(Page.A1, Page.A5, Page.A3); if (of.contains(Page.A1)) { System.out.println("Of contains A1"); } } }