enum,EnumMap,EnumSet

来源:互联网 发布:合肥工业大学网络公选 编辑:程序博客网 时间:2024/06/07 11:33

enum基本使用


package com.enumTest;

enum Shrubbery {
GROUND, CRAWLING, HANGING}

public class EnumClass {
public static void main(String[] args) {
for (Shrubbery s : Shrubbery.values()) {
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);
System.out.println(“s.getDeclaringClass:” + s.getDeclaringClass()
+ “getClass:” + s.getClass());
System.out.println(s.name());
System.out.println(“——————————-“);
}
String[] arrayString=”HANGING CRAWLING GROUND”.split(” “);
for (String s : arrayString) {
Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);
System.out.println(shrub);
}
}
}

  1. 每个enum实例(GROUND, CRAWLING, HANGING)都记录一个次序original(0,1,2).
    2.实现了Comparable接口,重写了compareTo按照 original来比较次序,且仅运行同一个enum类型实例做比较.
    3.equals 比较内存地址
    4.实现了 Serializable接口.

除了少量限制,我们可以把enum当作普通类型对待:
package com.enumTest;

public enum OzWitch {

//you must define enum instances firstly.WEST("west"), NORTH("north"), EAST("east"), SOUTH("south");private String description;//even if the constructor is public .. , it's nonsense!private OzWitch(String description) {    this.description = description;}public String getDescription() {    return description;}public static void main(String[] args) {    for (OzWitch witch : OzWitch.values()) {        System.out.println(witch + ":" + witch.getDescription());    }}

}

enum 类型可以用于switch 语句中

.switch(integer or enum){
case ….
}
enum Signal {
GREEN, YELLOW, RED
}

public class TrafficLight {
Signal color = Signal.RED;

public void change() {    switch (color/*枚举实例*/) {    //case ** 被强制用color类型的实例    case RED:        color = Signal.GREEN;        break;    case GREEN:        color = Signal.YELLOW;        break;    case YELLOW:        color = Signal.RED;        break;    }}public String toString() {    return "The traffic light is " + color;}public static void main(String[] args) {    TrafficLight t = new TrafficLight();    for (int i = 0; i < 7; i++) {        System.out.println(t);        t.change();    }}

}

关键字 enum 与 java.lang.Enum 的区别:
我们看以下代码:

enum Explore { HERE, THERE }

public class Reflection {
public static Set analyze(Class

package com.enumTest;
//枚举中的枚举
public enum Course {
//定义三个枚举实例
APPETIZER(Food.Appetizer.class),
MAINCOURSE(Food.MainCourse.class),
COFFEE(Food.Coffee.class);
//定一个域 用来得到 每个实例中包含的实例
private Food[] allFood;

//构造器获得一个枚举类型中的所有实例  //这个构造器 ,通过入参获取该入参对应的所有实例Course(Class<? extends Food> clazz) {    allFood = clazz.getEnumConstants();}//随机获取一个枚举(如 APPETIZER)中的枚举实例(如 SALAD,SOUP,RED_WINE)中的一个public Food randomSelection() {    return Enums.random(allFood);}

public static void main(String[] args) {
for (int i = 0; i < Course.values().length; i++) {
for (Course course : Course.values()) {
Food food = course.randomSelection();
System.out.println(food);
}
System.out.println(“———–”);
}
另外,还有一种简洁的组织方式(随便选择一种即可,个人倾向第一种,clear!):

public enum Meal2 {APPETIZER(Food.Appetizer.class),MAINCOURSE(Food.MainCourse.class),DESSERT(Food.Dessert.class),COFFEE(Food.Coffee.class);private Food[] values;private Meal2(Class<? extends Food> kind) {736 Thinking in Java Bruce Eckelvalues = kind.getEnumConstants();}public interface Food {enum Appetizer implements Food {SALAD, SOUP, SPRING_ROLLS;}enum MainCourse implements Food {LASAGNE, BURRITO, PAD_THAI,LENTILS, HUMMOUS, VINDALOO;}enum Dessert implements Food {TIRAMISU, GELATO, BLACK_FOREST_CAKE,FRUIT, CREME_CARAMEL;}enum Coffee implements Food {BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,LATTE, CAPPUCCINO, TEA, HERB_TEA;}}public Food randomSelection() {return Enums.random(values);}public static void main(String[] args) {for(int i = 0; i < 5; i++) {for(Meal2 meal : Meal2.values()) {Food food = meal.randomSelection();System.out.println(food);}System.out.println("---");}}} /* Same output as Meal.java *///:~

EnumSet

1.其操作比HashSet快,基于long的存储
2.EnumSet 中的元素 必须是 enum类型,初始化后元素的顺序与enum实例定义顺序一致

import java.util.EnumSet;public class EnumSets {    public static void main(String[] args) {        EnumSet<AlarmPoints> points = EnumSet.noneOf(AlarmPoints.class);        points.add(AlarmPoints.BATHROOM);        System.out.println(points);        points.addAll(EnumSet.of(AlarmPoints.STAIR1, AlarmPoints.STAIR2,                AlarmPoints.KITCHEN));        System.out.println(points);        points = EnumSet.allOf(AlarmPoints.class);        // points.removeAll(EnumSet.of(AlarmPoints.STAIR1,AlarmPoints.STAIR2,AlarmPoints.KITCHEN));        System.out.println(points);        // 参数 rangefrom,rangeTo 都包含        points.removeAll(EnumSet.range(AlarmPoints.STAIR1, AlarmPoints.STAIR2));        System.out.println(points);        //求一个差集        points = EnumSet.complementOf(points);        System.out.println(points);    }}

EnumSet基于long(64bit)构造, 通过EnumSet result = noneOf(elementType);初始化,EnumSet中的元素用一个bit来表示其存在。所以,如果初始化的enum元素个数超过64个则会增加long个数,如果小于64个,则会只有一个long的内存空间。
(如源码: elements 用来存元素)
/**
* Bit vector representation of this set. The 2^k bit indicates the
* presence of universe[k] in this set.
*/
private long elements = 0L;

EnumMap

1.key 必须是一个指定(构造器初始)的enum的实例,内部由数组实现,速度快
2.初始化后元素的顺序与enum实例定义顺序一致,其他操作与Map类似
3.实现 多路分发( multiple dispatching)

//命令模式 1.通常有一个仅有一个单一方法的接口interface Command {    void action();}public class EnumMaps {    public static void main(String[] args) {        EnumMap<AlarmPoints, Command> em = new EnumMap<AlarmPoints, Command>(                AlarmPoints.class);        //em 的键只允许是初始化定义的   AlarmPoints.class 的实例        em.put(AlarmPoints.KITCHEN, new Command() {            // 命令模式 2. 从该接口实现有各自不同行为的 子实现            @Override            public void action() {                System.out.println("Kitchen Fire!");            }        });        em.put(AlarmPoints.BATHROOM, new Command() {            @Override            public void action() {                System.out.println("Bathroom Fire!");            }        });        for(Map.Entry<AlarmPoints,Command> e:em.entrySet()){            System.out.println("  e.getKey()  " +e.getKey());            e.getValue().action();        }        try {            em.get(AlarmPoints.UTILITY).action();        } catch (Exception e ) {            e .printStackTrace();        }     }}

常量指定方法 (constantspecific methods)

public enum ConstantSpecificMethod {    DATE_TIME {        String getInfo() {            return DateFormat.getDateInstance().format(new Date());        }    },    CLASSPATH {        String getInfo() {            return System.getenv("CLASSPATH");        }    },    VERSION {        String getInfo() {            return System.getProperty("java.version");        }    };    //声明一个抽象方法(或者普通方法——默认行为方法,后边再说)    abstract String getInfo();    public static void main(String[] args) {        for (ConstantSpecificMethod constantSpecMethod : values()) {            System.out.println("\\s"+constantSpecMethod.getInfo());        }    }}

这个也称为表驱动的代码(详见< Code Complete>)。与命令模式很相似,只不过命令模式的通用接口,在这里由enum类代替。
oop不同类关联不同行为,而使用常量方法,每个实例就是一个独立的类型(当然,并不等同于“类”)。上例中一个enum类似乎被当作“超类”对待,具体到每个实例通过getInfo()表现出不同的行为,多态。

enum LikeClasses {WINKEN { void behavior() { print("Behavior1"); } },BLINKEN { void behavior() { print("Behavior2"); } },NOD { void behavior() { print("Behavior3"); } };abstract void behavior();}public class NotClasses {// void f1(LikeClasses.WINKEN instance) {} // Nope} /* Output:反编译后的代码Compiled from "NotClasses.java"abstract class LikeClasses extends java.lang.Enum{public static final LikeClasses WINKEN;public static final LikeClasses BLINKEN;public static final LikeClasses NOD;...*///

1.abstract class LikeClasses extends java.lang.Enum 一个抽象类
2.方法常量 就是这个抽象类的static 域( field)

**其中的抽象方法也可以换做 普通方法,那么默认赋予每个enum实例一个默认的方法:

public enum ConstantSpecificMethod {    DATE_TIME, // 赋予默认 getInfo()    /*     * { String getInfo() { return DateFormat.getDateInstance().format(new     * Date()); } },     */    CLASSPATH {        String getInfo() {            return System.getenv("CLASSPATH");        }    },    VERSION {        String getInfo() {            return System.getProperty("java.version");        }    };    String getInfo() {        System.out.println("default");        return null;    };    public static void main(String[] args) {        for (ConstantSpecificMethod constantSpecMethod : values()) {            System.out.println(constantSpecMethod.getInfo());        }    }}
1 0
原创粉丝点击