- 浏览: 166995 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
Mr.San:
binbinyouli 写道run(Enums.random( ...
java 枚举高级应用之状态机 -
Mr.San:
class Enums
{
private static ...
java 枚举高级应用之状态机 -
nocb:
对,Enums 没有
java 枚举高级应用之状态机 -
binbinyouli:
run(Enums.random(MONEY.getValue ...
java 枚举高级应用之状态机
枚举类型非常适合用来创建状态机,一个状态机通常可以拥有有限的几个状态,他通常根据输入,从一个状态进入到下一个状态。
下面是一个用枚举实现的自动售货机的例子,很简陋,但是表达清楚了意思就差不多了,也希望各位看官能指出不足之处。
package enums; import java.util.Random; /** * @描述 售货机可以接收的钞票金额和所有商品的价格 * @创建时间 2012-5-27 * @另请参照 */ public enum Input { /**五分硬币**/ NICKEL(5), /**一角硬币**/ DIME(10), /**两角五分**/ QUARTER(25), /**一块美金**/ DOLLAR(100), /**药膏2元**/ TOOTHPASTE(200), /**炸薯条75美分**/ CHIPS(75), /**苏打水1元**/ SODA(100),// /**肥皂5毛**/ SOAP(50), ABORT_TRANSACTION{ public int amount(){ throw new RuntimeException("退出时不能获取余额!"); } }, STOP{ public int amount(){ throw new RuntimeException("关机时不能获取余额!"); } }; //金额 int value; Input(int value){this.value = value;} Input(){} //返回该操作项的金额 int amount(){return value;} /** * @return 随机获取的操作 */ public static Input randomSelection(){ return values()[new Random(System.nanoTime()).nextInt(values().length)]; } }
package enums; import static enums.Input.*; import java.util.EnumMap; /** * 对自动售货机的状态分类 */ public enum Category { /**放入钞票**/ MONEY(NICKEL,DIME,QUARTER,DOLLAR), /**选择商品**/ ITEM_SELECTION(TOOTHPASTE,CHIPS,SODA,SOAP), /**退出**/ QUIT_TRANSACTION(ABORT_TRANSACTION), /**关机**/ SHUT_DOWN(STOP); private Input[] values; Category(Input... types){values = types;} public static EnumMap<Input, Category> categories = new EnumMap<Input, Category>(Input.class); public Input[] getValues(){ return values; } //初始化自动售货机状态集合 static { for (Category c : Category.class.getEnumConstants()) { for(Input input : c.values){ categories.put(input, c); } } } /**返回该操作项所属状态**/ public static Category categorize(Input input){ return categories.get(input); } }
package enums; import static enums.Category.*; /** * 自动售货机 */ public class VendingMachine { //当前运行状态 private static State state = State.RESTING; //当前余额 private static int amount = 0; //当前选择商品 private static Input selection = null; /**持续状态,不能做其他操作**/ enum StateDuration{TRANSIENT} /** * 运行状态 */ enum State{ /**初始界面**/ RESTING{ void next(Input input){ switch (Category.categorize(input)) { case MONEY: amount += input.amount(); System.out.println("放入金额:"+input.amount()+"美分"); state = ADDING_MONEY; break; case SHUT_DOWN: state = TERMINAL; break; default: state = RESTING; break; } } }, /**选择商品**/ ADDING_MONEY{ void next(Input input){ switch (Category.categorize(input)) { case MONEY: amount += input.amount(); System.out.println("再次放入金额:"+input.amount()+"美分,您的余额是:"+amount+"美分"); break; case ITEM_SELECTION: selection = input; System.out.println("选择商品:"+input); if(amount < input.amount()){ System.out.println("你的余额不够购买商品:"+input); state = ADDING_MONEY; }else state = DISPENSING; break; case QUIT_TRANSACTION: state = GIVING_CHANGE; break; case SHUT_DOWN: state = TERMINAL; break; default: state = ADDING_MONEY; break; } } }, /**发出商品,交易成功**/ DISPENSING(StateDuration.TRANSIENT){ void next(){ System.out.println("交易成功!请拿好您的商品:"+selection); //扣除购买商品的金额 amount -= selection.amount(); state = GIVING_CHANGE; } }, /**找零**/ GIVING_CHANGE(StateDuration.TRANSIENT){ void next(){ if(amount > 0){ System.out.println("请拿好您的找零:"+amount+"美分"); amount = 0; } state = TERMINAL; } }, /**交易终止**/ TERMINAL{ void output(){ System.out.println("交易结束"); } }; private boolean isTransient = false; /**当前是否是瞬时状态(即不可以做其他操作)**/ public boolean isTransient(){return this.isTransient;} State(){} State(StateDuration stateDuration){this.isTransient = true;} //默认方法(在瞬时状态时做其他操作时被调用) void next(Input input){ System.out.println("该状态不能做其他操作!");} //默认方法(在非瞬时状态时不做操作时被调用) void next(){ System.out.println("请选择一个操作!");} //默认方法(查看余额) void output(){System.out.println("您的余额还剩:"+amount+"美分");} } //执行一个操作 public static void run(Input gen){ if(state!=State.TERMINAL){ if(state.isTransient()){ state.next(); }else{ state.next(gen); } }else{ state.output(); } } //测试 public static void main(String[] args) { // TODO Auto-generated method stub int i = 0; while(true){ switch (state) { case RESTING: run(Enums.random(MONEY.getValues())); break; case ADDING_MONEY: //如果金额不足 if(i > 0){ run(Enums.random(MONEY.getValues())); i = 0; }else{ run(Enums.random(ITEM_SELECTION.getValues())); i++; } break; case TERMINAL: run(Input.STOP); return; default: run(null); break; } } } }
测试写的不怎么好。没那么多时间。
评论
4 楼
Mr.San
2016-07-27
binbinyouli 写道
run(Enums.random(MONEY.getValues()));
Enums从哪里来?
Enums从哪里来?
class Enums { private static java.util.Random rand = new java.util.Random(); public static <T extends Enum<T>> T random(Class<T> ec) { System.out.print("随机抽取" + ec + "中的一个元素:"); return random(ec.getEnumConstants()); } public static <T> T random(T[] values){ int index = rand.nextInt(values.length); System.out.println(".index: " + index); return values[index]; } }
3 楼
Mr.San
2016-07-27
class Enums { private static java.util.Random rand = new java.util.Random(); public static <T extends Enum<T>> T random(Class<T> ec) { System.out.print("随机抽取" + ec + "中的一个元素:"); return random(ec.getEnumConstants()); } public static <T> T random(T[] values){ int index = rand.nextInt(values.length); System.out.println(".index: " + index); return values[index]; } }
2 楼
nocb
2013-05-12
对,Enums 没有
1 楼
binbinyouli
2013-03-25
run(Enums.random(MONEY.getValues()));
Enums从哪里来?
Enums从哪里来?
发表评论
-
System.getProperty("file.encoding") 究竟获取的是什么编码
2018-07-04 16:18 1293一般是获取编译main class的文件编码,但是这个编码是由 ... -
分享一个自己 写的httpclient工具类
2018-01-26 13:13 784package com.fastwork.bm.util; ... -
二进制运算
2016-06-05 21:27 546一、有关位运算的基础知识总结 位运算包括:& ... -
java 插入排序
2015-08-12 11:41 537public static int[] insertSor ... -
tomcat gzip 压缩配置,实现文件自动压缩的功能
2015-04-13 14:56 3151项目使用的是extjs作为前端框架,这样就需要加载大 ... -
java 根据IP地址获取对应的地域信息
2015-03-24 12:01 1527/**根据IP地址获取地域信息 * @param ip ... -
正则表达式小结
2014-08-22 20:53 6111.Matcher 中的带参数的reset方法可以重复使用 ... -
javax.servlet.ServletException: PermGen space
2014-04-20 22:11 656将eclipse 里面的 vm arguments 加入以下 ... -
java 枚举中的枚举
2012-05-27 14:34 1615package enums; import java.u ... -
Java 枚举高级应用之责任链模式
2012-05-27 14:31 2094看 thinking in java 枚举那 ... -
java 位运算小计
2012-04-20 19:32 909二进制数据 分为原码,反码 和补码 。 做位运算的时候都是用 ...
相关推荐
java枚举状态机
java枚举结果类、根据状态值获取枚举值 Controller: /** 模块类型枚举 */ model.addAttribute("mType", ModuleTypeEnum.ModuleTypeShow()); ftl: value="${mType.key}:${mType.value}” </#list>
java枚举小例子,简单了解枚举的用法,适合初学者使用。
列举java 枚举相关信息列举java 枚举相关信息列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息
Java高新技术_java5的枚举的基本应用
NULL 博文链接:https://janeky.iteye.com/blog/463611
JAVA的枚举实例以及应用
简单总结java枚举类型,适合java初学者
java枚举类型的说说明,详细阐述了枚举类型的使用和注意事项
java 枚举ppt 枚举定义 用普通类模拟枚举 带构造方法的枚举 带抽象方法的枚举 单例与枚举 枚举与类集
理解java枚举类型
JAVA枚举JAVA枚举
一个关于JAVA枚举类型的MHT文件,包含JAVA枚举类型的用法,以及JDK版本的问题。
Java枚举的应用, 具体代码
Java枚举类型.pdf
本文详尽地论述了Java枚举与设计模式的关系
自己的LabVIEW枚举状态机
java高级编程 Enum枚举 包括枚举的例子,问题 及一些文档,是复习的好资源
关于java枚举的一个实例,
NULL 博文链接:https://rensanning.iteye.com/blog/2013734