【问题标题】:Problems that we use a BiMap to solve我们使用 BiMap 解决的问题
【发布时间】:2013-03-09 17:39:33
【问题描述】:

我正在审查 Google 的 Guava API 的功能,并且遇到了我在“真实世界编程”体验中从未见过的数据结构,即 BiMap。这种构造的唯一好处是能够快速检索给定值的键吗?是否存在使用 BiMap 最好地表达解决方案的任何问题?

【问题讨论】:

    标签: java guava bimap


    【解决方案1】:

    任何时候您都希望能够进行反向查找而无需填充两个地图。例如一个电话目录,您希望通过姓名查找电话号码,但也希望进行反向查找以从号码中获取姓名。

    【讨论】:

    • 没有两张地图怎么办? BiMap 肯定必须使用两个地图并隐藏这个事实吗?
    • 是的,它可能确实使用了两张地图,但您不必填充两张地图并管理所有这些。
    • @digitaljoel:不太可能,确实如此。见the source
    • @jlordo, @AmirAfghani:这是旧版番石榴的克隆。当前实现HashBiMapdoes no such thing,保存nearly 40% on memory from the traditional pair of HashMaps。 (ImmutableBiMap 类似。)
    • 不用担心。 (HashBiMap的重写也是超新的,一两周前才和Guava 14一起发布。另外,我是重写的,所以我对这类东西特别感兴趣。)
    【解决方案2】:

    Louis 提到了在 BiMap 实现中可能节省的内存。这是包装两个 Map 实例无法获得的唯一内容。不过,如果您让我们为您包装 Map 实例,we can take care of a few edges cases。 (你可以自己处理所有这些,但为什么要麻烦呢?:))

    • 如果您调用put(newKey, existingValue),我们将立即出错以保持两个映射同步,而不是在意识到它与另一个映射中的现有映射冲突之前将条目添加到一个映射。 (如果您确实想覆盖现有值,我们会提供 forcePut。)我们为插入 null 或其他无效值提供了类似的保护措施。
    • BiMap views 使两个映射保持同步:如果您从原始 entrySetentrySet 中删除一个元素,则其对应的条目也会从反向中删除。我们在Entry.setValue 做同样的事情。
    • 我们处理序列化:A BiMap 及其逆保持“连接”,并且条目仅被序列化一次。
    • 我们提供inverse() 的智能实现,以便foo.inverse().inverse() 返回foo,而不是包装器的包装器。
    • 我们覆盖values() 以返回Set。该集合与您从 inverse().keySet() 获得的相同,只是它保持与原始 BiMap 相同的迭代顺序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-23
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多