如何将LinkedHashMap特定条目添加至另一个并实现重做功能?
Got it,结合你是在写绘图程序的场景,应该是想实现撤销/重做的恢复逻辑对吧?你的思路方向是对的,但直接按大小遍历可能会有重复覆盖的问题,咱们来捋清楚怎么高效适配你的需求:
先明确前提
你有两个初始完全一致的LinkedHashMap:
currentMap:经过撤销操作后,已删除部分条目(当前的绘图状态)fullMap:保留了初始完整状态(未被撤销修改的全部绘图元素)
你的目标是通过重做操作,把currentMap中被撤销删除的条目逐步或一次性恢复回来。
1. 全量重做:一次性恢复到完整状态
如果是想一键把所有撤销的操作都还原,直接基于fullMap覆盖currentMap即可,两种实现方式可选:
// 方式一:直接替换引用(不需要保留原currentMap对象时用) currentMap = new LinkedHashMap<>(fullMap); // 方式二:清空后重新插入(需要保留原currentMap对象引用时用,比如绑定了UI组件) currentMap.clear(); currentMap.putAll(fullMap);
2. 单步重做:每次恢复最近删除的一条(更适配绘图程序的逐步操作)
因为LinkedHashMap是按插入顺序存储的,我们可以利用这个特性找到被删除的条目,实现逐步重做:
实现步骤
- 遍历
fullMap的所有条目,筛选出currentMap中不存在的条目(这些就是被撤销删除的内容) - 按插入顺序的逆序(对应最近删除的条目),每次添加一条到
currentMap中
代码示例
// 收集fullMap中有但currentMap中没有的条目(按初始插入顺序排列) List<Map.Entry<Object, Object>> missingEntries = new ArrayList<>(); for (Map.Entry<Object, Object> entry : fullMap.entrySet()) { // 假设每个绘图元素有唯一标识作为Key,用containsKey判断准确性更高 if (!currentMap.containsKey(entry.getKey())) { missingEntries.add(entry); } } // 单步重做:添加最近被删除的那条(撤销通常是删最后插入的元素,所以取集合最后一个) if (!missingEntries.isEmpty()) { Map.Entry<Object, Object> entryToRestore = missingEntries.get(missingEntries.size() - 1); currentMap.put(entryToRestore.getKey(), entryToRestore.getValue()); // 这里可以添加绘图刷新逻辑,比如触发UI重绘 }
如果要实现“逐步添加直到达到fullMap大小”,只需要每次点击重做按钮时重复执行上面的单步逻辑,直到currentMap.size() == fullMap.size()即可。
额外小提示(针对绘图程序优化)
其实在绘图程序中,更推荐用操作历史栈来实现撤销/重做,比保存两个完整Map更省内存:
- 用两个栈:
undoStack(存储已执行的操作,比如AddShape、DeleteShape)、redoStack(存储已撤销的操作) - 每次新增图形:执行添加逻辑,把
AddShape操作压入undoStack,清空redoStack - 撤销:从
undoStack弹出最近操作,执行反向逻辑(比如Add的反向是Delete),把操作压入redoStack - 重做:从
redoStack弹出最近操作,执行正向逻辑,压入undoStack
不过既然你已经重构到当前版本,上面的Map适配方案完全可以满足需求~
内容的提问来源于stack exchange,提问作者Guid
相关产品推荐
相关产品推荐

