在很多遊戲和應用程式中經常會用到回退功能,相當於ctrl+z。下面是使用Java實現undo功能
具體代碼如下:
import java.lang.reflect.Method;import java.util.LinkedList;import java.util.List;public class Undo<T> {private LinkedList<T> primaryList = new LinkedList<T>();//快照列表private LinkedList<List> snapshotList = new LinkedList<List>();//上一次操作調用的方法private Method lastOperation;//上一次操作調用的方法參數private Object[] lastOperationArgs;//拍快照,每操作一次拍下快照private void takeSnapshot() {List<T> snapshot = new LinkedList<T>();for (T element : primaryList) {snapshot.add(element);}snapshotList.add(snapshot);}//從最新的快照恢複private void restoreFromSnapshot() {//pollLast()擷取並移除此列表的最後一個元素;如果此列表為空白,則返回 null。List<T> snapshot = snapshotList.pollLast(); primaryList.clear();for (T element : snapshot) {primaryList.add(element);}}//設定上次操作private void setLastInvokedOperation(String methodName, Object... params) {try {this.lastOperation = this.getClass().getMethod(methodName, this.getParamTypes(params));} catch (Exception e) {if (setLastMethodParamsGeneric(methodName, params)==false){e.printStackTrace();}}this.lastOperationArgs = params;} //設定上一個方法的參數private boolean setLastMethodParamsGeneric(String methodName, Object... params) {Method[] methods = this.getClass().getMethods();for (int i=0; i<methods.length; i++) {if (this.isMethodMatch(methods[i], methodName, params)) {this.lastOperation = methods[i];return true;}}return false;}//判斷方法是否匹配private boolean isMethodMatch(Method method, String methodName, Object... params){if (!method.getName().equalsIgnoreCase(methodName)) {return false;}Class<?>[] paramTypes = method.getParameterTypes();if (paramTypes.length != params.length) {return false;}for (int i=0; i<params.length; i++) {if (!paramTypes[i].isAssignableFrom(params[i].getClass())) {return false;}}return true;}//擷取參數的類型private Class<?>[] getParamTypes(Object... params) {Class<?>[] paramTypes = new Class<?>[params.length];for (int i=0; i<params.length; i++) {paramTypes[i] = params[i].getClass(); }return paramTypes;}//執行上一個方法private void invokeLastMethod() {try {this.lastOperation.invoke(this, this.lastOperationArgs);} catch (Exception e) {e.printStackTrace();} }//刪除操作public void delete(Integer beginIndex, Integer endIndex) {//刪除操作之前拍下快照this.takeSnapshot();for (int i=beginIndex; i<=endIndex; i++) {primaryList.remove(beginIndex);}this.setLastInvokedOperation("delete", beginIndex, endIndex);}//插入操作public void insert(T element, Integer index) {//插入操作之前拍下快照this.takeSnapshot();primaryList.add(index, element);this.setLastInvokedOperation("insert", element, index);}//修改操作public void modify(T element, Integer index) {//修改操作之前拍下快照this.takeSnapshot();primaryList.set(index, element);this.setLastInvokedOperation("modify", element, index);}//重做,取消複原public void redo() {//執行上次操作的方法this.invokeLastMethod();} //撤銷public void undo() {//重最新的快照中恢複this.restoreFromSnapshot();}public String toString() {return this.primaryList.toString();}public static void main(String[] args) {Undo<String> ell = new Undo<String>();ell.insert("hey", 0);System.out.println(ell);ell.redo();System.out.println(ell);ell.undo();System.out.println(ell);ell.redo();System.out.println(ell);ell.undo();System.out.println(ell);ell.undo();System.out.println(ell);}}
ok,問題解決。