【问题标题】:how to create the following map of map in Scala如何在Scala中创建以下地图地图
【发布时间】:2015-04-08 15:06:02
【问题描述】:

我是 Scala 新手:如何在 Scala 中创建以下“地图地图”:

“外”地图 +-------------------------+------------------------ --------+ |钥匙 |价值 | +-------------------------+------------------------ --------+ | (employeID, currencyID) | (valueDate, 一组 CashFlow) | +-------------------------+------------------------ --------+

“外部”映射中的值也是一个映射:

“内”图 +-----------+------+ |钥匙 |价值 | +-----------+------+ |值日期 |套现金流| +-----------+------+

具有以下类型:

  • employeeID:内部
  • currencyID:整数
  • valueDate: java.util.Date
  • 现金流集:Set[com.company.CashFlow]

以下内容无法编译(需要覆盖 +=、-= 等):

myMap = new mutable.HashMap[(Int, Int), java.util.TreeMap[Date, mutable.Set[CashFlow]] with mutable.MultiMap[Date, CashFlow].withDefaultValue(new util.TreeMap[Date, mutable.Set[CashFlow]] with mutable.MultiMap[Date, CashFlow]

要求:

  • 地图必须是可变的
  • 按值日期排序
  • 对于一个 valueDate,我可以有多个现金流
  • 我想避免检查 (employeeID, currencyID) 上的密钥是否存在,即如果密钥不存在,myMap(emp1, ccy1).addBinding(date1, cashFlow1) 不应失败。 相反,它应该自动创建一个新的空排序 MultiMap 并使用 (date1, cashFlow1) 对其进行初始化

【问题讨论】:

    标签: scala scala-collections


    【解决方案1】:

    不用MultiMap也可以创建:

    import scala.collection.mutable._, JavaConverters._, java.util.TreeMap
    
    val myMap = new mutable.HashMap[(Int, Int), mutable.Map[Date, Set[CashFlow]]]{ 
        override def apply(k: (Int, Int)) = 
           getOrElseUpdate(k, new TreeMap[Date, mutable.Set[CashFlow]].asScala) 
    }
    myMap: scala.collection.mutable.Map[(Int, Int),scala.collection.mutable.Map[java.util.Date,scala.collection.mutable.Set[CashFlow]]] = Map()
    

    需要override def apply,因为withDefaultValue 将始终返回相同的值。

    也可以使用标准包装器从 java 的 TreeMap 创建 MultiMap

    import scala.collection.convert.Wrappers._
    
    //This wrapper will hold your Java's TreeMap inside, and delegate all operations to it
    scala> def newTreeMultiMap[K, V]: MultiMap[K, V] = new JMapWrapper(new TreeMap[K, Set[V]]) with MultiMap[K, V]
    newTreeMultiMap: [K, V]=> scala.collection.mutable.MultiMap[K,V]
    
    scala> val myMap = new HashMap[(Int, Int), MultiMap[Int, String]]{ override def apply(k: (Int, Int)) = getOrElseUpdate(k, newTreeMultiMap[Int, String]) }
    myMap: scala.collection.mutable.Map[(Int, Int),scala.collection.mutable.MultiMap[java.util.Date,CashFlow]] = Map()
    

    我认为它应该在标准库中,但没有找到。

    示例(我使用Int 而不是Date 来表明排序有效):

    scala> val myMap = new HashMap[(Int, Int), MultiMap[Int, String]]{ override def apply(k: (Int, Int)) = getOrElseUpdate(k, newTreeMultiMap[Int, String]) }
    myMap: scala.collection.mutable.Map[(Int, Int),scala.collection.mutable.MultiMap[Int,String]] = Map()
    
    scala> myMap(0 -> 0).addBinding(4, "aaa") //no exceptions on myMap(0 -> 0) with empty Map
    res27: scala.collection.mutable.MultiMap[Int,String] = Map(4 -> Set(aaa))
    
    scala> myMap(0 -> 0).addBinding(2, "aaa") //should be before 4
    res28: scala.collection.mutable.MultiMap[Int,String] = Map(2 -> Set(aaa), 4 -> Set(aaa))
    
    scala> myMap(0 -> 0).addBinding(5, "aaa") //should be after 4
    res29: scala.collection.mutable.MultiMap[Int,String] = Map(2 -> Set(aaa), 4 -> Set(aaa), 5 -> Set(aaa))
    
    scala> myMap(0 -> 0).addBinding(4, "bbb")
    res30: scala.collection.mutable.MultiMap[Int,String] = Map(2 -> Set(aaa), 4 -> Set(aaa, bbb), 5 -> Set(aaa))
    
    scala> myMap(0 -> 0).toList //finally use the order
    res31: List[(Int, scala.collection.mutable.Set[String])] = List((2,Set(aaa)), (4,Set(aaa, bbb)), (5,Set(aaa)))
    
    scala> myMap(0 -> 1).addBinding(2, "aaa") 
    res18: scala.collection.mutable.MultiMap[Int,String] = Map(2 -> Set(aaa))
    

    【讨论】:

    • 非常感谢!使用包装解决方案完美工作
    • 我的测试速度太快了:我不知道这是否是一个错误,但是对于每个 (Int, Int) 元组都重复使用了相同的多图,所以它对我不起作用。你知道如何为每个不同的元组隐式地创建一个新的多图吗?
    • 是的,我已经更新了答案(参见 val myMap = ) - 只需用 override def apply(k: K) = getOrElseUpdate(k, newTreeMultiMap[K, V]) 覆盖 HashMapapply 方法,而不是使用 withDefaultValue
    猜你喜欢
    • 2011-02-09
    • 1970-01-01
    • 2013-06-07
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多