当前位置: 首页 > 知识库问答 >
问题:

将映射转换为字符串时意外删除

杨君之
2023-03-14
abstract trait SchedulingActor[I <: SchedulingActor.Item[I]] extends Actor {

    private val log = LoggerFactory.getLogger(classOf[SchedulingActor[I]])

    private var schedule = Map[Ticket, (I, Cancellable)]()
    private var ticketMap = Map[Int, Ticket]()

    protected def delay(msg: Any, item: I): Cancellable
    protected def initiate(item: I): Unit

    protected def schedule(item: I) = self ! item

    private def currentTickets(item: I) = item.ids.flatMap(ticketMap.get(_))
    protected def linkedItems(ids: Seq[Int]) = ids.flatMap(ticketMap.get(_)).map(schedule(_)._1)

    protected case class Ticket() {

        def collect(item: I) = {
            schedule += this -> (item, delay(this, item))
            ticketMap ++= item.ids.map(_ -> this)
        }

        def update(item: I) = {
            schedule += this -> (item, schedule(this)._2)
        }

        def cancel() = {
            schedule(this)._1.cancel()
            schedule(this)._2.cancel()
            drop()
        }

        def drop() = {
            ticketMap = ticketMap.filterKeys(!schedule(this)._1.ids.contains(_))
            schedule -= this
        }

        def item = schedule(this)._1
    }

    def receive = {

        case item: I =>
            // Check if we're overwriting any currently scheduled
            try {
                log.debug("Scheduling item: " + item)
                log.debug("Checking for tickets: " + ticketMap)
            }
            catch {
                case ex: Throwable =>
                    log.error("Strange error", ex)
            }
            currentTickets(item).foreach { ticket =>
                log.debug("Checking current ticket: " + ticket)
                ticket.item.purge(item) match {
                    case upd if upd.ids.nonEmpty =>
                        log.debug("Updating schedule: " + upd)
                        ticket.update(upd)
                    case _ =>
                        log.debug("Cancelling ticket: " + ticket)
                        ticket.cancel()
                }
            }
            // Schedule the replacement now
            log.debug("Collecting ticket for: " + item)
            Ticket().collect(item)
            log.debug("Scheduled replacement: " + item)

        case ticket: Ticket =>
            initiate(ticket.item)
            ticket.drop()
    }
}

object SchedulingActor {

    trait Item[T <: Item[T]] {
        val ids: Set[Int]
        def cancel(): Unit
        def purge(newItem: T): T
    }
}

在将ticketMap转换为字符串时,它究竟为什么要尝试调用“drop”方法

共有1个答案

尉迟鸿熙
2023-03-14

通过检查堆栈跟踪,我可以推断出问题源于方法drop(),特别是下面一行:

ticketMap = ticketMap.filterKeys(!schedule(this)._1.ids.contains(_))

通过将其更改为:

    ticketMap = ticketMap.filterNot(kv => schedule(this)._1.ids.contains(kv._1))

我假设filterKeys的实现使用与mapKeys类似的机制,后者使用惰性计算。因此,直到下一次引用ticketMap时才调用filterKeys,此时消息已经处理完毕。这显然不是我们想要的行为。

 类似资料:
  • 很抱歉重复了这个问题,但我的问题是其他的。我有一个从json-string解析到map的JSON解析器方法。但是json-string有一个值,这个值也是json-string。大概是这样的: 因此,我的解析方法: 我在客户端得到响应: ?但是随后我得到一个错误,IDE告诉我,是一个字符串。 那么,我如何用我的UserData获得这个LinkedHashMap呢?对不起,为了我的英语。谢谢你。

  • 这个问题不难,我已经用自己的方法解决了,但我想听听你的意见,也许有什么方法可以让这成为一个改进的选择?Java 8-11。

  • 控制台输出 编辑:

  • 问题内容: 如何将经典字符串转换为f字符串? 输出: 所需的输出: 问题答案: f字符串是 语法 ,而不是对象类型。您不能将任意字符串转换为该语法,该语法会创建一个字符串对象,而不是相反。 我假设您想用作模板,因此只需在对象上使用方法: 如果要提供可配置的模板服务,请创建一个包含所有可以插值的字段的名称空间字典,并与调用语法一起使用以应用名称空间: 然后,用户可以在字段中的名称空间中使用任何键(或