第19章 枚举类型

枚举类型

public enum Spiciness {
    /**
     * 具名值,枚举类型的实例,常量
     * 按照常量书写的惯例它们都用大写字母表示
     */
    NOT, MID, MEDIUM, HOT, FLAMING
}
import org.testng.annotations.Test;

public class SpicinessTest {

    /**
     * 在你创建enum时,编译器会自动添加一些有用的特性
     *
     */
    @Test(enabled = false)
    public void testSimpleEnumUse() {
        Spiciness howHot = Spiciness.MEDIUM;
        // 输出MEDIUM。 编译器自动添加toString方法,显示enum实例的名字
        System.out.print(howHot);
    }

    /**
     * 尽管enum看起来像是一种新的数据类型,但是这个关键字知识为enum生成对应的类时,产生某些编译行为
     */
    @Test(enabled = true)
    public void testEnumOrder() {
        // static values()方法,是由编译器添加的static方法,Enum类中并没有values方法,按照enum常量的声明顺序,产生这些常量值构成的数组
        for(Spiciness s : Spiciness.values()) {
            // ordinal()方法,用来表示某个特定enum常量的声明顺序
            System.out.println(s + ", ordinal " + s.ordinal());
        }
    }
}

运行结果

基本enum特性

public enum Shrubbery {
    /**
     * 创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum
     */
    GROUND, CRAWLING, HANGING
}
import org.testng.annotations.Test;

public class ShrubberyTest {
    @Test(enabled = true)
    public void testShrubbery() {
        for(Shrubbery s : Shrubbery.values()) {
            // ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始
            System.out.println(s + " ordinal: " + s.ordinal());
            System.out.println(s.compareTo(Shrubbery.CRAWLING) + " ");
            System.out.println(s.equals(Shrubbery.CRAWLING) + " ");
            System.out.println(s == Shrubbery.CRAWLING);
            // 在enum实例上调用getDeclaringClass()方法,我们就能知道其所属的enum类
            System.out.println(s.getDeclaringClass());
            // name()方法返回enum实例声明时的名字,这与使用toString()方法效果相同
            System.out.println(s.name());
            System.out.println("----------------------");
        }
        for(String s : "HANGING CRAWLING GROUND".split(" ")) {
            /**
             * valueOf()方法根据给定的名字返回相应的enum实例,如果不存在给定名字的实例,将会抛出异常
             * s == null, throw new NullPointerException
             * s not exist throw new IllegalArgumentException
             */
            Shrubbery shrubbery = Enum.valueOf(Shrubbery.class, s);
            System.out.println(shrubbery);
        }
    }
}

运行结果

向enum中添加新方法

public enum OzWitch {
    /** 如果你打算定义自己的方法,那么必须在enum实例序列的最后添加一个分号
     *  Java要求你必须先定义enum实例,如果在定义enum实例之前定义了任何方法或属性,那么编译时就会得到错误信息
     */
    WEST("Miss Gulch, aka the Wicked Witch of the West"),
    NORTH("Glinda, the Good Witch of the North"),
    EAST("Wicked Witch of the East, wearer of the Ruby " + "Slippers, crushed by Dorothy's house"),
    SOUTH("Good by inference, but missing");

    private String description;
    OzWitch(String description) {
        this.description = description;
    }
    public String getDescription() {
        return description;
    }
}
import org.testng.annotations.Test;

public class OzWitchTest {
    @Test
    public void test() {
        for(OzWitch witch : OzWitch.values()) {
            System.out.println(witch + ": " + witch.getDescription());
        }
    }
}

运行结果

覆盖enum中的方法

public enum SpaceShip {
    SCOUT, CARGO, TRANSPORT, CRUISER, BATTLESHIP, MOTHERSHIP;

    /**
     * 覆盖enum的toString()方法
     * @return
     */
    public String toString() {
        String id = name();
        String lower = id.substring(1).toLowerCase();
        return id.charAt(0) + lower;
    }
}
import org.testng.annotations.Test;

public class SpaceShipTest {
    @Test
    public void test() {
        for(SpaceShip s : SpaceShip.values()) {
            System.out.println(s);
        }
    }
}

运行结果

switch

public class Burrito {
    Spiciness degree;
    public Burrito(Spiciness degree) {
        this.degree = degree;
    }

    /**
     * enum有一个特别实用的特性,即它可以在switch语句内使用
     */
    public void describe() {
        System.out.print("This burrito is ");
        switch (degree) {
            case NOT:
                System.out.println("not spicy at all.");
                break;
            case MID:
            case MEDIUM:
                System.out.println("a little hot.");
                break;
            case HOT:
            case FLAMING:
                default:
                    System.out.println("maybe too hot.");

        }
    }
}
import org.testng.annotations.Test;

public class BurritoTest {

    @Test(enabled = true)
    public void testDescribe() {
        Burrito
                plain = new Burrito(Spiciness.NOT),
                greenChile = new Burrito(Spiciness.MEDIUM),
                jalapeno = new Burrito(Spiciness.HOT);
        plain.describe();
        greenChile.describe();
        jalapeno.describe();

    }
}

运行结果

EnumSet

public enum AlarmPoints {
    STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3,
    OFFICE4, BATHROOM, UTILITY, KITCHEN
}
import org.testng.annotations.Test;

import java.util.EnumSet;
/**
 * 使用static import 简化enum常量的使用
 */
import static com.dmw.enumerated.AlarmPoints.*;

public class EnumSetTest {
    @Test
    public void test() {
        // Empty set,EnumSet中的元素必须来自一个enum
        EnumSet<AlarmPoints> points = EnumSet.noneOf(AlarmPoints.class);

        points.add(BATHROOM);
        System.out.println(points);

        points.addAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));
        System.out.println(points);

        points = EnumSet.allOf(AlarmPoints.class);
        System.out.println(points);

        points.removeAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));
        System.out.println(points);

        points.removeAll(EnumSet.range(OFFICE1, OFFICE4));
        System.out.println(points);

        points = EnumSet.complementOf(points);
        System.out.println(points);
    }
}

运行结果

EnumMaps

import java.util.EnumMap;
import java.util.Map;

import static com.dmw.enumerated.AlarmPoints.*;

public class EnumMaps {
    public static void main(String[] args) {
        EnumMap<AlarmPoints, Command> em = new EnumMap<>(AlarmPoints.class);
        em.put(KITCHEN, new Command() {
            @Override
            public void action() {
                System.out.println("Kitchen fire");
            }
        });

        em.put(BATHROOM, new Command() {
            @Override
            public void action() {
                System.out.println("Bathroom alert!");
            }
        });

        for(Map.Entry<AlarmPoints, Command> e : em.entrySet()) {
            System.out.println(e.getKey() + ":");
            e.getValue().action();
        }

        try {
            em.get(UTILITY).action();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

interface Command {
    void action();
}

运行结果

常量相关方法

import java.text.DateFormat;
import java.util.Date;

/**
 * 1. Java的enum有一个非常有趣的特性,即它允许程序员为enum实例编写方法,从而为每个enum实例赋予各自不同的行为
 * 2. 通过相应的enum实例,我们可以调用对应的方法。这通常也称为表驱动的代码(table-driven code, 和命令模式有一定的相似之处)
 * 3. 每个enum元素(例如DATE_TIME)都是一个ConstantSpecificMethod的static final实例
 */
public enum ConstantSpecificMethod {
    DATE_TIME {
        @Override
        String getInfo() {
            return DateFormat.getDateInstance().format(new Date());
        }
    },
    CLASSPATH {
        @Override
        String getInfo() {
            return System.getenv("CLASSPATH");
        }
    },
    VERSION {
        @Override
        String getInfo() {
            return System.getProperty("java.version");
        }
    };

    abstract String getInfo();
}
import org.testng.annotations.Test;

public class ConstantSpecificMethodTest {
    @Test
    public void test() {
        for(ConstantSpecificMethod csm : ConstantSpecificMethod.values()) {
            System.out.println(csm.getInfo());
        }
    }
}

比匿名内部类更加简洁高效

import java.util.EnumSet;

/**
 * 与使用匿名内部类相比较,定义常量相关方法的语法更高效、简洁
 */
public class CarWash {
    public enum Cycle {
        UNDERBODY {
            @Override
            void action() {
                System.out.println("Spraying the underbody");
            }
        },
        WHEELWASH {
            @Override
            void action() {
                System.out.println("Washing the wheels");
            }
        },
        PREWASH {
            @Override
            void action() {
                System.out.println("Loosening the dirt");
            }
        },
        BASIC {
            @Override
            void action() {
                System.out.println("The basic wash");
            }
        },
        HOTWAX {
            @Override
            void action() {
                System.out.println("Applying hot wax");
            }
        },
        RINSE {
            @Override
            void action() {
                System.out.println("Rinsing");
            }
        },
        BLOWDRY {
            @Override
            void action() {
                System.out.println("Blowing dry");
            }
        };

        abstract void action();
    }

    EnumSet<Cycle> cycles = EnumSet.of(Cycle.BASIC, Cycle.RINSE);

    public void add(Cycle cycle) {
        cycles.add(cycle);
    }

    public void washCar() {
        for(Cycle c : cycles) {
            c.action();
        }
    }

    @Override
    public String toString() {
        return cycles.toString();
    }

    public static void main(String[] args) {
        CarWash wash = new CarWash();
        System.out.println(wash);
        wash.washCar();
        // Order of addition is unimportant
        wash.add(Cycle.BLOWDRY);
        // Duplicates ignored
        wash.add(Cycle.BLOWDRY);
        wash.add(Cycle.RINSE);
        wash.add(Cycle.HOTWAX);
        System.out.println(wash);
        wash.washCar();
    }
}

运行结果

猜你喜欢

转载自blog.csdn.net/DMW2016/article/details/83624064