如何在scala中实现嵌套映射

时间:2015-11-01 03:27:42

标签: scala oop dictionary

我正在尝试在play框架中的scala中实现嵌套映射。 我想要实现的是一个Map[String, Map[Long,Int]]类型的地图。我无法分配父地图的值,父地图本身就是地图。应用程序正在正确编译,但值未更新。你能否告诉我我做错了什么以及如何将地图值分配给另一张地图?

import java.util.concurrent.ConcurrentHashMap
import scala.collection._
import scala.collection.convert.decorateAsScala._
import scala.collection.JavaConversions.mapAsScalaMap

case class Events(eventType: String, timeStamp: Long)

object Events {

  var eventMap = new ConcurrentHashMap[String, ConcurrentHashMap[Long,Int]]()

  def save(events: Events) = {
    var eventsKey: String = ""
    var count: Int = 1
    var timeKey: Long = 0L
    var newEntry: Boolean = false
    eventsKey = events.eventType
    var countMap = new ConcurrentHashMap[Long,Int]()
    countMap.clear()

    if (eventMap.containsKey(eventsKey)) {
      countMap = eventMap.get(eventsKey) // this is not working
      timeKey = events.timeStamp
      if (countMap.containsKey(timeKey)) { 
        count = countMap(timeKey) + 1
        countMap.put(timeKey, count)
        eventMap.put(eventsKey, countMap)
      } // End of counter check
      else {
        newEntry = true
      }
    } // End of if event key check
    else {
      newEntry = true
    } // End of else event key check

    if (newEntry) {
      countMap.putIfAbsent(timeKey, 1)
      eventMap.putIfAbsent(eventsKey, countMap)
    }
  }
}

1 个答案:

答案 0 :(得分:2)

问题正在发生,因为您只在if中设置临时Observable,并且您仍然需要if之外的此值。这将使您的程序始终将timeKey作为timeStamp的第一个eventType插入:

0

要解决此问题,只需将代码移出Events.save(Events("aa", 222)) // {aa={0=1}} Events.save(Events("aa", 333)) // {aa={0=1, 333=1}} Events.save(Events("aa", 333)) // {aa={0=1, 333=2}} Events.save(Events("bb", 444)) // {aa={0=1, 333=2}, bb={0=1}}

即可
if

现在,当你跑步时,你得到:

...     
var newEntry: Boolean = false
eventsKey = events.eventType
timeKey = events.timeStamp // <--- This fixes it
var countMap = new ConcurrentHashMap[Long,Int]()
countMap.clear()

if (eventMap.containsKey(eventsKey)) {
  countMap = eventMap.get(eventsKey) //this is not working

  if (countMap.containsKey(timeKey)) {
    count = countMap(timeKey) + 1
...

附加

我知道你没有问过这件事,但我认为有一个更惯用的scala代码会很好:

Events.save(Events("aa", 222))     // {aa={222=1}}

Events.save(Events("aa", 333))     // {aa={333=1, 222=1}}

Events.save(Events("aa", 333))     // {aa={333=2, 222=1}}

Events.save(Events("bb", 444))     // {aa={333=2, 222=1}, bb={444=1}}

PS:我将case class Event(eventType: String, timeStamp: Long) object Event { val eventMap = new ConcurrentHashMap[String, ConcurrentHashMap[Long,Int]]() def save(event: Event) = { val Event(eventKey, timeKey) = event val countMap = eventMap.getOrElse(eventKey, new ConcurrentHashMap[Long,Int]()) val count = countMap.getOrElse(timeKey, 0) + 1 countMap.put(timeKey, count) eventMap.put(eventKey, countMap) } } 重命名为Events

PS2:注意当你以更惯用的方式编程时,你偶然发现的bug是多么困难。 :)