public enum Spiciness {
NOT,MILD,MEDIUM,HOT,FLAMING
}
这里创建了一个Spiciness的枚举类型,它有5个具名值。枚举类型的实例是常量,用大写字母表示。
public class SimpleEnumUse {
public static void main(String[] args) {
Spiciness spiciness=Spiciness.HOT;
System.out.println(spiciness);
for(Spiciness s:Spiciness.values()){
System.out.println(s+" ordinal "+s.ordinal());
}
}
}
ordinal()方法表示某个特定的enum常量的声明顺序(从0开始);
values()方法按照常量的声明顺序,生成由这些常量值构成的数组。
name()方法返回enum实例声明时的名字,这与使用toString()效果相同。
valueOf()是在Enum中定义的static方法,根据给定的名字返回相应的enum实例。
public class Burrito {
Spiciness degree;
public Burrito(Spiciness degree){
this.degree=degree;
}
public void describe(){
System.out.println("This burrito is : ");
switch (degree){
case NOT:
System.out.println("NOT");
break;
case MILD:
System.out.println("MILD");
break;
case MEDIUM:
System.out.println("MEDIUM");
break;
case HOT:
System.out.println("HOT");
break;
case FLAMING:
System.out.println("FLAMING");
break;
}
}
public static void main(String[] args) {
Burrito
burrito=new Burrito(Spiciness.HOT),
burrito1=new Burrito(Spiciness.MILD),
burrito2=new Burrito(Spiciness.FLAMING);
burrito.describe();
burrito1.describe();
burrito2.describe();
}
}
由于switch是要在有限的集合中进行选择,所以与enum正式绝佳的组合。
public class OzWitchTest {
public static void main(String[] args) {
for (OzWitch o:OzWitch.values()){
System.out.println(o+" : "+o.getDescription());
}
}
}
每个枚举实例返回对自身的描述。提供一个构造器,专门负责这个额外的信息,然后提供一个方法,返回这个描述信息。
定义自己的方法,必须在enum实例序列的最后添加一个分号,同时必须先定义enum实例。
enum中的构造器和方法与普通的类没有区别。
public enum SpaceShip {
AA,BB,CC,DD,EE;
@Override
public String toString() {
String name = name();
String s = name.substring(1).toLowerCase();
return name.charAt(0)+s;
}
public static void main(String[] args) {
for(SpaceShip spaceShip:SpaceShip.values()){
System.out.println(spaceShip);
}
}
}
覆盖enum的toString()方法。通过调用name()方法取得SpaceShip的名字,然后修改为只有首字母大写的格式。
public class TrafficLight {
enum Signal{
RED,GREEN,YELLOW
}
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;
}
}
@Override
public String toString() {
return "The trafficLight 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 Search{HITHER,YON}
public class UpcastEnum {
public static void main(String[] args) {
Search[] vals=Search.values();
Enum e=Search.HITHER; //Upcast
//e.values(); Enum没有values()方法
for(Enum en:e.getClass().getEnumConstants()){
System.out.println(en);
}
}
}
values()方法是由编译器添加的static方法。如果将enum实例向上转型为Enum,那么values()方法则不可访问。
Class中的getEnumConstants()方法可以获取enum所有实例。
public class Enums {
private static Random rand=new Random(47);
public static > T random(Class ec){
return random(ec.getEnumConstants());
}
public static T random(T[] values){
return values[rand.nextInt(values.length)];
}
}
enum Activity{SITTING,LYING,STANDING,HOPPING,RUNNING,DODGING,JUMPING,FALLING,FLYING}
public class RandomTest {
public static void main(String[] args) {
for(int i=0;i<20;i++){
System.out.print(Enums.random(Activity.class)+" ");
}
}
}
从枚举实例中进行随机选取。
Enums中将Class
public enum SecurityCategory {
STOCK(Security.Stock.class),
BOND(Security.Bond.class);
Security[] values;
SecurityCategory(Class extends Security> kind){
values=kind.getEnumConstants(); //获得枚举所有实例
}
interface Security{
enum Stock implements Security {SHORT,LONG,MARGIN}
enum Bond implements Security {MUNICIPAL,JUNK}
}
public Security randomSelection(){
return Enums.random(values); //随机选取实例
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
SecurityCategory category=Enums.random(SecurityCategory.class); //随机选取实例
System.out.println(category+" : "+category.randomSelection());
}
}
}
枚举中嵌套枚举。对于枚举而言,实现接口是使其子类化的唯一方法。
enum AlarmPoints{
STAIR1,STAIR2,LOBBY,OFFICE1,OFFICE2,OFFICE3,OFFICE4,BATHROOM,UTILITY,KITCHEN
}
EnumSet适用于枚举的集合,其中的元素必须来自一个enum。
interface Command{
void action();
}
public class EnumMaps {
public static void main(String[] args) {
EnumMap em=new EnumMap(AlarmPoints.class);
em.put(AlarmPoints.KITCHEN, new Command() {
@Override
public void action() {
System.out.println("Kitchen fire!");
}
});
em.put(AlarmPoints.BATHROOM, new Command() {
@Override
public void action() {
System.out.println("Bathroom alert!");
}
});
em.put(AlarmPoints.LOBBY, new Command() {
@Override
public void action() {
System.out.println("Lobby run!");
}
});
for(Map.Entry entry:em.entrySet()){
System.out.println(entry.getKey()+" :"+entry.getValue());
entry.getValue().action();
}
try{
em.get(AlarmPoints.UTILITY).action();
}catch (Exception e){
System.out.println(e);
}
}
}
EnumMap其中的key必须来自一个enum。没有为key调用put()方法来存入值得话,其对应值就是null。
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();
public static void main(String[] args) {
for(ConstantSpecificMethod csm:ConstantSpecificMethod.values()){
System.out.println(csm.getInfo());
}
}
}
为enum实例编写方法,为每个enum实例赋予各自不同的行为。
这里编写一个石头剪刀布游戏。
enum Outcome {
WIN,LOSE,DRAW
}
public interface Item {
Outcome compete(Item item);
Outcome eval(Paper paper);
Outcome eval(Scissors scissors);
Outcome eval(Rock rock);
}
class Paper implements Item{
@Override
public Outcome compete(Item item) {
return item.eval(this);
}
@Override
public Outcome eval(Paper paper) {
return Outcome.DRAW;
}
@Override
public Outcome eval(Scissors scissors) {
return Outcome.WIN;
}
@Override
public Outcome eval(Rock rock) {
return Outcome.LOSE;
}
@Override
public String toString() {
return "布";
}
}
class Scissors implements Item{
@Override
public Outcome compete(Item item) {
return item.eval(this);
}
@Override
public Outcome eval(Paper paper) {
return Outcome.LOSE;
}
@Override
public Outcome eval(Scissors scissors) {
return Outcome.DRAW;
}
@Override
public Outcome eval(Rock rock) {
return Outcome.WIN;
}
@Override
public String toString() {
return "剪刀";
}
}
class Rock implements Item{
@Override
public Outcome compete(Item item) {
return item.eval(this);
}
@Override
public Outcome eval(Paper paper) {
return Outcome.WIN;
}
@Override
public Outcome eval(Scissors scissors) {
return Outcome.LOSE;
}
@Override
public Outcome eval(Rock rock) {
return Outcome.DRAW;
}
@Override
public String toString() {
return "石头";
}
}
public class RoShamBo1 {
static final int SIZE=10;
private static Random random=new Random(66);
public static Item newItem(){
switch (random.nextInt(3)){
default:
case 0:
return new Paper();
case 1:
return new Scissors();
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
public interface Competitor> {
Outcome compete(T competitor);
}
public class RoShamBo {
public static > void match(T a,T b){
System.out.println(a+" vs "+b+" : "+a.compete(b));
}
public static & Competitor> void play(Class rsbClass,int size){
for(int i=0;i
public enum RoShamBo2 implements Competitor {
PAPER(DRAW,LOSE,WIN), //顺序很重要
SCISSORS(WIN,DRAW,LOSE), //与构造器的形参对应
ROCK(LOSE,WIN,DRAW);
private Outcome vPAPER,vSCISSORS,vROCK;
RoShamBo2(Outcome paper,Outcome scissors,Outcome rock){
vPAPER=paper;
vSCISSORS=scissors;
vROCK=rock;
}
@Override
public Outcome compete(RoShamBo2 competitor) {
switch (competitor){
default:
case PAPER:return vPAPER;
case ROCK:return vROCK;
case SCISSORS:return vSCISSORS;
}
}
public static void main(String[] args) {
RoShamBo.play(RoShamBo2.class,10);
}
}
利用构造器初始化每个enum实例,并以“一组”结果作为参数。
比如PAPER vs SCISSORS,match()方法中a是PAPER ,b是SCISSORS,由于重写了compete()方法,返回vSCISSORS。构造器初始化了每个enum实例,PAPER中vSCISSORS是第二位,也就是LOSE。
public enum RoShamBo5 implements Competitor {
PAPER,SCISSORS,ROCK;
static EnumMap>
table=new EnumMap>(RoShamBo5.class);
static {
for(RoShamBo5 it:RoShamBo5.values()){
table.put(it,new EnumMap(RoShamBo5.class));
}
initRow(PAPER,Outcome.DRAW,Outcome.LOSE,Outcome.WIN);
initRow(SCISSORS,Outcome.WIN,Outcome.DRAW,Outcome.LOSE);
initRow(ROCK,Outcome.LOSE,Outcome.WIN,Outcome.DRAW);
}
static void initRow(RoShamBo5 it,Outcome vPAPER,Outcome vSCISSORS,Outcome vROCK){
EnumMap row=RoShamBo5.table.get(it);
row.put(RoShamBo5.PAPER,vPAPER);
row.put(RoShamBo5.SCISSORS,vSCISSORS);
row.put(RoShamBo5.ROCK,vROCK);
}
@Override
public Outcome compete(RoShamBo5 it) {
return table.get(this).get(it);
}
public static void main(String[] args) {
RoShamBo.play(RoShamBo5.class,10);
}
}
import static enum_test.Outcome.*;
public enum RoShamBo6 implements Competitor {
PAPER,SCISSORS,ROCK;
private static Outcome[][] table={
{DRAW,LOSE,WIN},//PAPER
{WIN,DRAW,LOSE},//SCISSORS
{LOSE,WIN,DRAW}//ROCK
};
@Override
public Outcome compete(RoShamBo6 competitor) {
return table[this.ordinal()][competitor.ordinal()];
}
public static void main(String[] args) {
RoShamBo.play(RoShamBo6.class,10);
}
}