【问题标题】:Why is there no mutable TreeMap in Scala?为什么 Scala 中没有可变的 TreeMap?
【发布时间】:2011-05-30 17:34:33
【问题描述】:

是时间不够、技术问题还是不应该存在的原因?

【问题讨论】:

    标签: scala collections map tree mutable


    【解决方案1】:

    这只是一个缺失的情况,可能最终会被填补。没有理由不这样做,并且在某些情况下它会比不可变树快得多(因为修改需要使用 log(n) 对象创建不可变树,只有 1 棵具有可变树)。


    编辑:事实上它是在 2.12 中填写的。

    Mutable TreeMap.

    (也有对应的Set。)

    【讨论】:

    • 您能否解释一下为什么它需要 log(n) 而不是 n 使用不可变树创建对象?我想一旦修改所有节点都会创建。
    • @Bin,不可变数据结构的一个优点是您可以利用“结构共享”。由于只需要更改树的一部分,其余部分与原始部分相同,因此无需重新创建保持不变的部分,您只需包含对原始部分的引用即可。
    【解决方案2】:

    同时您可以使用 Java TreeMap,这正是您所需要的。

    val m = new java.util.TreeMap[String, Int]()
    m.put("aa", 2)
    m.put("cc", 3)
    

    【讨论】:

    • Java 缺少所有的高阶函数,所以没那么有趣……
    • import collection.JavaConverters._ 后跟 new java.util.TreeMap[String, Int]().asScala。您将获得 SortedMap 行为和高阶函数,但不会获得 SortedMap 函数。
    • TreeMaps 或 SortedMaps 似乎都不是 supported by JavaConverters?
    • 对于信息,java TreeMap 是“唯一的”java,但它提供了一些 scala 等效项没有的方法(例如 floorEntry)。在某些情况下非常实用。
    【解决方案3】:

    我认为原因是拥有可变变体并没有带来很大的好处。在其他答案中提到了一些情况,当可变映射可能更有效时,例如在替换已经存在的值时:可变变体将节省新节点的创建,但复杂性仍然是 O(登录 n).

    如果您想保留对映射的共享引用,可以使用ImmutableMapAdaptor,它将任何不可变映射包装到可变结构中。

    【讨论】:

    • ImmutableMapAdaptor 已被弃用
    【解决方案4】:

    您还会注意到TreeSet 也没有可变的等价物。这是因为它们共享公共基类RedBlack,并且保持Trees 按元素或键排序的底层数据结构是red-black tree。我不太了解这种数据结构,但它非常复杂(与其他 Map 相比,插入和删除非常昂贵),所以我认为这与未包含可变变体有关。

    基本上,这可能是因为底层数据结构不容易可变,所以TreeMap 不是。所以,要回答你的问题,这是一个技术问题。不过绝对可以做到,只是没有太多用例。

    【讨论】:

    • Java 中的 HashSet 是一个可变的红黑树。红黑树本质上并不是一成不变的。
    • @Craig 不,它们不是天生的,但有一些原因(我认为它们主要是基于性能的)为什么你不想实现可变变体。
    【解决方案5】:

    可变TreeMap 可能存在性能原因,但通常您可以像使用可变映射一样使用不可变映射。您只需将其分配给var 而不是val。它与 HashMap 相同,具有可变和不可变的变体:

    val mh = collection.mutable.HashMap[Int, Int]()
    var ih = collection.immutable.HashMap[Int, Int]()
    mh += (1 -> 2)
    ih += (1 -> 2)
    mh // scala.collection.mutable.HashMap[Int,Int] = Map(1 -> 2)
    ih // scala.collection.immutable.HashMap[Int,Int] = Map(1 -> 2)
    

    【讨论】:

    • 并且不保留对 mh, ih 先前值的任何引用。这对我来说常常是一个障碍。有时,您确实需要一个可共享的可变结构......
    • @Paul 我想你需要的是ImmutableMapAdaptor
    猜你喜欢
    • 2017-01-13
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 2015-05-16
    • 2019-04-20
    • 2011-05-30
    • 2011-05-04
    相关资源
    最近更新 更多