【问题标题】:Java: Stacked (layered) maps behind a Map interface?Java:地图接口后面的堆叠(分层)地图?
【发布时间】:2013-06-16 20:24:23
【问题描述】:

我需要一个包含堆叠地图的 Map impl,我可以使用 push()pop(),如果它们属于被推送/弹出的地图,则这些值将被“添加”或“删除”。并且这些值将被搜索顶部/底部(或可选的底部/顶部)。

在 JDK 或其他地方是否有现成的 impl?

例子:

  • 堆栈
    • 地图4
      • foo => aaa
      • 酒吧 => 45
    • 地图3
      • 酒吧 => 22
    • 地图2
      • foo => ccc
      • baz => 呜呜
    • 地图1

为此,get("baz") 将返回 "uuu"get("foo") 将返回 "aaa"size() 将返回 3 等。 这有点像 JavaScript 的原型继承。

one impl 我希望有一些更复杂的 impl,它不会在我每次调用任何方法时真正遍历所有层。读取方法将比 push()/pop() 更频繁,因此在此期间可能会有一些预计算。

【问题讨论】:

  • 你将如何在这里创建“外部地图”?
  • 在 JDK 中没有这样的内置结构,但是使用 LinkedList<Map<K, V>> 来编写你的实现会很容易
  • 如果你需要栈是线程安全的,你可以使用LinkedBlockingDeque<Map<K, V>>
  • 与Properties比较,可以有另一个Properties映射作为默认值。

标签: java map stacked layered


【解决方案1】:

您可以将 Stack 作为包装器。有一个 Map (这里的 String 是地图的名称)。将推送和弹出作为 API 公开。您问题中有趣的部分是,定义推送和弹出?这些方法的签名实际上是什么样子的?实际上,您要达到的目标不是很清楚?

【讨论】:

    【解决方案2】:

    因此,JDK 中没有这样的内置结构,但可以使用包含Maps 的LinkedList 来实现。

    LinkedList 实现了所有三个ListQueueDeque,也许有点矫枉过正,但是哦……

    示例代码如下;然而,Map 接口并没有真正被遵守(好奇你会怎么做.equals().hashCode()?甚至不谈论.clear()):

    public final class StackedMap<K, V>
        implements Map<K, V>
    {
        private final Map<K, V> NO_MAP = new HashMap<K, V>();
        private final LinkedList<Map<K, V>> maps = new LinkedList<>();
    
        private Map<K, V> currentMap = NO_MAP;
    
        public void push(Map<K, V> map)
        {
            maps.push(map);
            currentMap = map;
        }
    
        public Map<K, V> pop()
        {
            return currentMap = maps.pop();
        }
    
        @Override
        public V get(K key)
        {
            V ret;
    
            for (final Map<K, V> map: maps)
                if ((ret = map.get(key)) != null)
                    break;
            return ret;
        }
    
        // etc
    }
    

    未经测试等

    【讨论】:

    • 关于 LinkedList 是多余的,Java 有一个 Stack 类,但它的文档说“Deque 接口及其实现提供了一组更完整和一致的 LIFO 堆栈操作,应该优先使用此类”
    • @fge 与 is-a 相比,has-a 关系如何?考虑到这个问题,我认为这样做会更好
    • 当然我可以自己写,但我希望有一些更复杂的 impl,它不会在我每次调用任何方法时真正遍历所有层。读取方法将比 push()/pop() 更频繁,因此可能会有一些预计算。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多