如何在 Scala 中创建以下地图的地图
how to create the following map of map in Scala
我是 Scala 新手:如何在 Scala 中创建以下 "map of map":
"Outer" map
+-------------------------+-------------------------------+
| Key | Value |
+-------------------------+-------------------------------+
| (employeID, currencyID) | (valueDate, set of CashFlow) |
+-------------------------+-------------------------------+
"outer"图中的值也是一个图:
"Inner" map
+-----------+------------------+
| Key | Value |
+-----------+------------------+
| valueDate | set of CashFlow |
+-----------+------------------+
具有以下类型:
- 员工ID:整数
- 货币ID:整数
- 值日期:java.util.Date
- 现金流集:集[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) 初始化它
不用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
将始终 return 与您相同的值。
也可以使用标准包装器从 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))
我是 Scala 新手:如何在 Scala 中创建以下 "map of map":
"Outer" map +-------------------------+-------------------------------+ | Key | Value | +-------------------------+-------------------------------+ | (employeID, currencyID) | (valueDate, set of CashFlow) | +-------------------------+-------------------------------+
"outer"图中的值也是一个图:
"Inner" map +-----------+------------------+ | Key | Value | +-----------+------------------+ | valueDate | set of CashFlow | +-----------+------------------+
具有以下类型:
- 员工ID:整数
- 货币ID:整数
- 值日期:java.util.Date
- 现金流集:集[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) 初始化它
不用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
将始终 return 与您相同的值。
也可以使用标准包装器从 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))