多维数组实现状态图的核心是用二维数组statetablecurrentstate查表映射状态转移,行=状态编号、列=事件编号,单元格存下一状态;需编号连续从0开始,封装为statemachine类并处理边界、非法转移和状态通知。

用多维数组实现状态图,核心是把状态转移逻辑映射成一张“查表”结构——行代表当前状态,列代表输入事件,单元格里存的是下一个状态。它不追求理论完备性,适合嵌入式、游戏状态机或教学场景等轻量需求。
状态与事件如何编号对齐
先明确有限的状态集合(如 IDLE、RUNNING、PAUSED、ERROR)和输入事件(如 START、STOP、PAUSE、RESUME),给每个分配唯一整数索引:
- 状态:IDLE=0,RUNNING=1,PAUSED=2,ERROR=3
- 事件:START=0,STOP=1,PAUSE=2,RESUME=3
编号必须连续且从 0 开始,才能直接作为数组下标使用。建议用 public static final int 常量定义,避免魔法数字。
设计二维转移表:stateTable[currentState][event]
声明一个二维 int 数组,行数 = 状态总数,列数 = 事件总数。每个元素填入对应转移后的状态编号:
int[][] stateTable = {
{1, 0, 0, 0}, // IDLE 状态:START→RUNNING,其余事件保持 IDLE(或设为 -1 表示非法)
{2, 0, 2, 1}, // RUNNING:PAUSE→PAUSED,STOP→IDLE,RESUME 无效(可设 -1)
{1, 0, 2, 1}, // PAUSED:RESUME→RUNNING,STOP→IDLE,PAUSE 无变化
{3, 3, 3, 3} // ERROR:所有事件都维持 ERROR(或重置逻辑另写)
};
非法转移可填 -1,运行时检查并抛异常或忽略;若需默认行为(如日志警告),在状态更新前加判断即可。
封装状态机:用类管理当前状态与转移逻辑
避免裸数组操作,封装成 StateMachine 类:
- 内部维护 currentState 字段(初始值设为 IDLE)
- 提供 trigger(int event) 方法:检查 event 是否越界 → 查表获取 nextState → 验证 nextState 是否为 -1 → 更新 currentState 并返回 true/false 表示是否成功
- 可选添加 getStateName() 辅助方法,用字符串数组映射编号回可读名,便于调试
扩展提示:支持动作执行与状态进入/退出钩子
纯状态跳转不够实用。可在查表后,用另一个二维数组或 switch 拓展动作逻辑:
- 定义 actionTable[currentState][event] 存动作编号(如 0=none,1=startMotor,2=logError)
- 或在 trigger() 中增加回调接口:当从 RUNNING→PAUSED 时自动调用 pauseHandler()
- 更进一步,用枚举替代整数编号,自带名称和方法,类型更安全(但数组索引需改用 ordinal())
不复杂但容易忽略:边界检查、非法转移处理、状态变更通知,这三处补全才真正可用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











