【问题标题】:Why does my Map claim to have no keys after adding keys?为什么我的 Map 添加键后声称没有键?
【发布时间】:2017-11-15 21:44:39
【问题描述】:

我有一张 Int->Queue 的地图,我一次将一个条目添加到队列中。在过程结束时,我需要遍历键和值(因为我想将队列转换为数组),但 scala 说映射中没有键/值。下面的一些简化代码用于说明目的。这里发生了什么?下面m(4)的结果也令人费解。

import scala.collection.mutable.Queue

val m = Map[Int, Queue[Int]]().withDefaultValue(Queue[Int]())

m(1) += 10
res25: scala.collection.mutable.Queue[Int] = Queue(10)

m(1) += 10
res26: scala.collection.mutable.Queue[Int] = Queue(10, 10)

m(1)
res35: scala.collection.mutable.Queue[Int] = Queue(10, 10)

m(4)
res37: scala.collection.mutable.Queue[Int] = Queue(10, 10)

m.keys
res28: Iterable[Int] = Set()

m
res36: scala.collection.immutable.Map[Int,scala.collection.mutable.Queue[Int]] = Map()

使用 Scala 2.10.3。

【问题讨论】:

    标签: scala


    【解决方案1】:

    你永远不会在地图上添加任何东西。您将获得设置为默认值的可变队列并对其进行修改。

    【讨论】:

      【解决方案2】:

      是的,您必须检查给定索引处的Queue 是否已创建,但语法不必那么“费力”。

      import scala.collection.mutable.Queue
      val mutablemap = scala.collection.mutable.Map[Int, Queue[Int]]()
      
      mutablemap(9) = mutablemap.lift(9).fold(Queue(99))(_ += 99)
      mutablemap(2) = mutablemap.lift(2).fold(Queue(22))(_ += 22)
      mutablemap(9) = mutablemap.lift(9).fold(Queue(19))(_ += 19)
      mutablemap(2) = mutablemap.lift(2).fold(Queue(12))(_ += 12)
      
      mutablemap(9)  // res0: scala.collection.mutable.Queue[Int] = Queue(99, 19)
      mutablemap(2)  // res1: scala.collection.mutable.Queue[Int] = Queue(22, 12)
      

      更新

      进一步思考,您的原始设计并没有离题太远。

      import scala.collection.mutable.Queue
      val mutablemap = 
        scala.collection.mutable.Map[Int, Queue[Int]]().withDefault(_ => Queue[Int]())
      
      mutablemap(3) = mutablemap(3) += 37
      mutablemap(3) = mutablemap(3) += 45
      mutablemap(6) = mutablemap(6) += 60
      mutablemap(6) = mutablemap(6) += 62
      
      mutablemap(3)  // res0: scala.collection.mutable.Queue[Int] = Queue(37, 45)
      mutablemap(6)  // res1: scala.collection.mutable.Queue[Int] = Queue(60, 62)
      

      【讨论】:

      • 当你做 mutablemap(6) = mutablemap(6) += 62 时,是 O(1) 还是 O(N) 其中 N 是队列的长度?
      • 根据ScalaDocs page+= 方法“将单个元素附加到此缓冲区。这需要恒定的时间。”
      • 我想知道mutablemap(6) = 中的=。这是删除现有的 N 长度队列并用新队列替换它,还是由于引用的智能内部处理而导致 O(1)?
      • 如果整个操作都是 O(N),我会有点惊讶,但我真的不知道。
      • @foghorn 附加到队列是 O(1) 如前所述。访问一个 HashMap 元素实际上是 O(1),但是如果你的散列算法很差,这种性能会降低。还要记住计算密钥哈希码的成本。您的键是 Ints,所以这里不用担心。所以你可以说这个操作作为一个整体应该是O(1)。
      【解决方案3】:

      利用 puhlen 的回答:

      首先,我需要切换到可变地图。其次,withDefaultValue 的使用似乎与这个问题无关(这是违反直觉的)。

      val mutablemap = scala.collection.mutable.Map[Int, Queue[Int]]()
      

      在向映射中添加键值对时,我必须先费力地检查键是否存在(因为我不想破坏任何预先存在的键值对,因为我正在逐步建立队列):

      if (mutablemap.contains(key)) {
          // mutate the existing Queue
          mutablemap(key) += new_value
      } else {
          // key was not in map; start a new Queue
          mutablemap += key -> Queue[Int](first_value)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-10
        相关资源
        最近更新 更多