You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Circe对Map[K,V]类型数据进行编码

要实现Map[K, V]的Circe编解码,你需要为自定义键类型K分别实现KeyEncoder和KeyDecoder,值类型V直接用Circe的常规编解码派生即可。

完整实现示例

1. 基础依赖(sbt)

libraryDependencies ++= Seq(
  "io.circe" %% "circe-core" % "0.14.6",
  "io.circe" %% "circe-generic" % "0.14.6",
  "io.circe" %% "circe-parser" % "0.14.6"
)

2. 业务代码实现

import io.circe._
import io.circe.generic.semiauto._
import io.circe.syntax._

// 你定义的样例类
case class K(a1: String, a2: String)
case class V(b1: String, b2: String)

object K {
  // 方案1:用分隔符拼接K的字段作为键,性能更高,适合字段无特殊分隔符的场景,此处用|作为分隔符可自行替换
  implicit val kKeyEncoder: KeyEncoder[K] = (key: K) => s"${key.a1}|${key.a2}"
  implicit val kKeyDecoder: KeyDecoder[K] = (keyStr: String) => {
    keyStr.split('|') match {
      case Array(a1, a2) => Some(K(a1, a2))
      case _ => None
    }
  }

  /* 方案2:把K序列化为JSON字符串作为键,适合字段可能含任意字符的场景,取消注释即可使用
  implicit val kEncoder: Encoder[K] = deriveEncoder[K]
  implicit val kDecoder: Decoder[K] = deriveDecoder[K]
  implicit val kKeyEncoder: KeyEncoder[K] = (key: K) => key.asJson.noSpaces
  implicit val kKeyDecoder: KeyDecoder[K] = (keyStr: String) => io.circe.parser.parse(keyStr).flatMap(_.as[K]).toOption
  */
}

object V {
  // V是普通值类型,直接派生编解码器即可
  implicit val vEncoder: Encoder[V] = deriveEncoder[V]
  implicit val vDecoder: Decoder[V] = deriveDecoder[V]
}

// 测试用例
object CirceMapTest extends App {
  val testMap = Map(
    K("key1_part1", "key1_part2") -> V("val1_part1", "val1_part2"),
    K("key2_part1", "key2_part2") -> V("val2_part1", "val2_part2")
  )

  // 编码为JSON
  val json = testMap.asJson
  println(json.noSpaces)
  // 方案1输出示例:{"key1_part1|key1_part2":{"b1":"val1_part1","b2":"val1_part2"},"key2_part1|key2_part2":{"b1":"val2_part1","b2":"val2_part2"}}

  // 反序列化回Map[K,V]
  val decoded = json.as[Map[K, V]]
  println(decoded)
  // 输出:Right(Map(K(key1_part1,key1_part2) -> V(val1_part1,val1_part2), K(key2_part1,key2_part2) -> V(val2_part1,val2_part2)))
}

注意事项

  • 两种键序列化方案可以根据业务场景选择,核心要求是保证一个K实例对应唯一的字符串,且字符串可以反向解析回K实例
  • 如果不需要反序列化功能,可以只实现KeyEncoder即可

内容的提问来源于stack exchange,提问作者martav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 17:15:02