读书人

java 兑现undo和redo操作链表的一种实

发布时间: 2012-10-19 16:53:37 作者: rapoo

java 实现undo和redo操作链表的一种实现
今天在iteye论坛逛,发现有这么一道笔试题目:实现一个可以增加一个节点、删除某个区间的节点、修改某个节点、undo和redo的链表。
有个网友atomduan给这道题目的一种实现形式,现在我在他的代码上加了注释,利于理解。

import java.lang.reflect.Method;import java.util.LinkedList;import java.util.List;public class EditableLinkedList<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) {EditableLinkedList<String> ell = new EditableLinkedList<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);}}

运行结果:
[hey][hey, hey][hey][hey, hey][hey][]

读书人网 >编程

热点推荐