第19章枚举类型

1、关键字enum可以将一组具名的值的有限集合创意为一种新的类型,而这些具有的值可以作为常规的程序组件使用。
19.1 基本enum特性
1、

package com19;/*** Created by Panda on 2018/5/20.*/
enum Shrubbery{GROUND,CRAWLING,HANGING}
public class EnumClass {public static void main(String[] args) {for (Shrubbery s:Shrubbery.values()) {//ordinal() 方法返回一个int值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());System.out.println(s.name());System.out.println("-------------------");}/***GROUND  ordinal: 0-1falsefalseclass com19.ShrubberyGROUND-------------------CRAWLING  ordinal: 10truetrueclass com19.ShrubberyCRAWLING-------------------HANGING  ordinal: 21falsefalseclass com19.ShrubberyHANGING-------------------*/}
}

19.1.1 将静态导入用于enum
19.2向enum中添加新方法
1、除了不能继承自一个enum外,基本可以将enum看作一个常规的类。也就是可以向enum中添加方法,甚至可以有main方法
2、如果打算定义自己的方法,那么必须在enmu实力序列的最后添加一个分好。同时,Java要求必须先定义enum实例。如果在定义实例之前定义了任何方法或属性,那么在编译时就会得到错误信息。
3、Enum中的构造器与方法和普通的类没有区别,因为除了有少许控制之外,enum就是一个普通的类。所以,可以使用enum做许多事情。
19.2.1覆盖enum的方法
1、

package com19;/*** Created by Panda on 2018/5/20.*/
public enum SpaceShip {SCOUT,CARGO,TRAN,CURI,BATT,MOTH;public String toString(){String id=name();String lower=id.substring(1).toLowerCase();return id.charAt(0)+lower;}public static void main(String[] args) {for (SpaceShip s:values()) {System.out.println(s);}}
}

19.3 switch语句中的enum

package com19;/*** Created by Panda on 2018/5/20.*/
enum Signal{GREEN,YELLOW,RED,}
public class TrafficLight {Signal color=Signal.RED;public void change(){switch (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 trafficLight = new TrafficLight();for (int i = 0; i < 7; i++) {System.out.println(trafficLight);trafficLight.change();}}/*** The traffic light is  REDThe traffic light is  GREENThe traffic light is  YELLOWThe traffic light is  REDThe traffic light is  GREENThe traffic light is  YELLOWThe traffic light is  RED*/
}

19.4 values()的神秘之处
Values()是由编译器添加的static方法。
19.5实现,而非继承
1、enum继承自java.lang.Enum类。由于java不支持多重继承,所以enum不能再继承其他类。可以同时实现一个或多个接口。
19.6 随机选取
1、

package com19;import java.util.Random;/*** Created by Panda on 2018/5/20.*/
public class Enums {private static Random random= new Random(47);public static > T random(Class tClass){return  random(tClass.getEnumConstants());}public static  T random(T[] values){return values[random.nextInt(values.length)];}
}

19.7使用接口组织枚举
1、无法从enum继承子类。在一个接口的内部,创建实现该接口的枚举,以此奖元素进行分组,可以达到将枚举元素分类组织的目的。
19.8 使用EnumSet替代标志
1、不能从enum中删除或者添加元素。
2、EnumSet的优点是:说明一个二进制位是否存在,具有更好的表达能力,并且无需担心性能。

package com19下;import java.util.EnumSet;import static com19下.AlarmPoints.*;/*** Created by Panda on 2018/5/21.*/
public class EnumSets {//STAIRI1,STAIR2,LOBBY,OFFICE1,OFFICE2,OFFICE3,OFFICE4,OFFICE5,OFFICE,BATHROOM,UTILITY,KITCHENpublic static void main(String[] args) {EnumSet pointss = EnumSet.noneOf(AlarmPoints.class);pointss.add(BATHROOM);System.out.println(pointss);pointss.addAll(EnumSet.of(STAIRI1,STAIR2,KITCHEN));System.out.println(pointss);pointss=EnumSet.allOf(AlarmPoints.class);pointss.removeAll(EnumSet.of(STAIRI1,STAIR2,KITCHEN));System.out.println(pointss);pointss.removeAll(EnumSet.range(OFFICE1,OFFICE4));System.out.println(pointss);//创建一个其元素类型与指定枚举 set 相同的枚举 set,最初包含指定 set 中所不 包含的此类型的所有元素pointss=EnumSet.complementOf(pointss);System.out.println(pointss);}/*** [BATHROOM][STAIRI1, STAIR2, BATHROOM, KITCHEN][LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, OFFICE5, OFFICE, BATHROOM, UTILITY][LOBBY, OFFICE5, OFFICE, BATHROOM, UTILITY][STAIRI1, STAIR2, OFFICE1, OFFICE2, OFFICE3, OFFICE4, KITCHEN]*/
}

19.9 使用EnumMap
1、EnumMap是一种特殊的Map,要求其中的键(key)必须来自一个enum。
2、命令模式首先需要一个只有单一方法的接口,然后从该接口实现具有各自不同的行为的多个子类。

package com19下;import java.util.EnumMap;
import java.util.Map;import static com19下.AlarmPoints.BATHROOM;
import static com19下.AlarmPoints.KITCHEN;
import static com19下.AlarmPoints.UTILITY;/*** Created by Panda on 2018/5/21.*/
interface Command{ void action();}
public class EnumMaps {public static void main(String[] args) {EnumMap enumMap = new EnumMap(AlarmPoints.class);enumMap.put(KITCHEN, new Command() {@Overridepublic void action() {System.out.println("Kitchen fire");}});enumMap.put(BATHROOM, new Command() {@Overridepublic void action() {System.out.println("Bathroom alert");}});for(Map.Entry e:enumMap.entrySet()){System.out.println(e.getKey()+" ");e.getValue().action();}try{enumMap.get(UTILITY).action();}catch (Exception e){System.out.println(e);}}/*** BATHROOMBathroom alertKITCHENKitchen firejava.lang.NullPointerException*/
}

19.10常量相关的方法
1、程序员可以为enum实例编写方法,从而为每个enum实例赋予各自不同的行为。需要为enum定义一个或多个abstract方法,然后为每个enum实例实现该抽象方法。对于内部的enum的实例而言,其行为与一般的内部类并不相同。

package com19下;import java.util.EnumSet;/*** Created by Panda on 2018/5/21.*/
public class CarWash {public enum Cycle{UNDERBODY{void action(){System.out.println("Spraying the underbody");}},WHEELWASH{void action(){System.out.println("washing the wheels");}},PREWASH{void action(){System.out.println("Loosening the dirt");}},BASIC{void action(){System.out.println("The basic wash");}},HOTWAX{void action(){System.out.println("Applying hot wax");}},RINSE{void action(){System.out.println("Rinsing");}},BLOWDRY{void action(){System.out.println("Blowing dry");}};abstract void action();}EnumSet cycles = EnumSet.of(Cycle.BASIC,Cycle.RINSE);public void add(Cycle cycle){cycles.add(cycle);}public void washCar(){for (Cycle c:cycles) {c.action();}}public String toString(){return cycles.toString();}public static void main(String[] args) {CarWash carWash = new CarWash();System.out.println(carWash);carWash.washCar();carWash.add(Cycle.BLOWDRY);carWash.add(Cycle.BLOWDRY);  //忽略carWash.add(Cycle.RINSE);carWash.add(Cycle.HOTWAX);System.out.println(carWash);carWash.washCar();}/*** [BASIC, RINSE]The basic washRinsing[BASIC, HOTWAX, RINSE, BLOWDRY]The basic washApplying hot waxRinsingBlowing dry*/
}

19.11多路分发
1、Java只支持单路分发。也就是说,如果要执行的操作包含不知一个类型未知的对象时,那么Java的动态绑定机制只能处理其中一个的类型。
2、多路分发:多态只能发生在方法调用时,所以,如果想使用两路分发,就必须有两个方法调用:第一个方法调用决定第一个未知类型,第二个方法调用决定第二个未知的类型。利用多路分发,程序员必须为每一个类型提供一个实际的方法调用,如果要处理两个不同的类型体系,就需要为每个类型体系执行一个方法调用。
3、配置好多路分发需要很多工序,好处在于方法调用时的优雅的语法。
4、

package com19下;import java.util.Random;import static com19下.OutCome.DRAW;
import static com19下.OutCome.LOSE;
import static com19下.OutCome.WIN;/*** Created by Panda on 2018/5/21.*/interface Item{OutCome compete(Item it);OutCome eval(Paper p);OutCome eval(Scissors s);OutCome eval(Rock r);
}
class Paper implements Item{@Overridepublic OutCome compete(Item it) {return it.eval(this);}@Overridepublic OutCome eval(Paper p) {return DRAW;}@Overridepublic OutCome eval(Scissors s) {return WIN;}@Overridepublic OutCome eval(Rock r) {return LOSE;}public String toString(){return "paper";}
}
class Scissors implements Item{@Overridepublic OutCome compete(Item it) {return it.eval(this);}@Overridepublic OutCome eval(Paper p) {return LOSE;}@Overridepublic OutCome eval(Scissors s) {return DRAW;}@Overridepublic OutCome eval(Rock r) {return WIN;}public String toString(){return "Scissors";}
}class Rock implements Item{@Overridepublic OutCome compete(Item it) {return it.eval(this);}@Overridepublic OutCome eval(Paper p) {return WIN;}@Overridepublic OutCome eval(Scissors s) {return LOSE;}@Overridepublic OutCome eval(Rock r) {return DRAW;}public String toString(){return "Rock";}
}public class RoShamBo1{static final  int SIZE=20;private static Random random = new Random(47);public static Item newItem(){switch (random.nextInt(3)){default:case 0:return new Scissors();case 1:return new Paper();case 2:return new Rock();}}public static void match(Item a,Item b){System.out.println(a+" vs. "+b+": "+a.compete(b));}public static void main(String[] args) {for (int i = 0; i < SIZE; i++) {match(newItem(),newItem());}}}

19.11.1使用enum分发
1、使用构造器初始化每个enum实例,并以“一组”结果作为参数,这两者放在一块,形成类似查询表的结构。
19.11.2 使用常量相关的方法
19.11.3使用EnumMap分发
1、使用EnumMap能够实现“真正的”两路分发。EnumMap是为enum专门设计的一种性能非常好的特殊Map。
19.11.4使用二维数组
19.12总结


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部