首页 > 解决方案 > Scala Map[String, Int] 类铸造灾难

问题描述

在单元测试中相互断言Map[String, Int]我得到:

Map(bar -> 114, foo -> 5) did not equal Map("foo" -> 5, "bar" -> 114)

请注意,键没有在左侧引用,而是在右侧引用。

左边通过 Avro 序列化作为 GenericRecord 的一部分在 Kafka 中往返。右边是我这样构建的测试夹具:

program_int_args = Map[String, Int]("foo" -> 5, "bar" -> 114)

一旦我从 Kafka 取回它,我就会像这样解码 Avro 消息:

 val program_int_args_ =
        record.get("program_int_args")
          .asInstanceOf[java.util.Map[String, Integer]]
          .asScala
          .toMap[String, Integer]
          .mapValues(Integer2int(_))

问题:

  1. 为什么来自 GenericRecord 后没有引号?
  2. 为什么存在来自构建地图的引号?
  3. 我怎样才能使这些相等?

根据 Thomas Klager 的评论,我检查了键的类别,确实它们是不同的:

class org.apache.avro.util.Utf8 did not equal class java.lang.String

所以更新问题:

类型如何Utf8成为 a 中的键Map[String, Int]但不等于与 a 相同的数据String

标签: javascalaavro

解决方案


我认为由于类型擦除,两种转换

.asInstanceOf[java.util.Map[String, Integer]]

.toMap[String, Integer]

不要真正检查地图中键和值的类型。

你可以试试

val program_int_args_ =
        record.get("program_int_args")
          .asInstanceOf[java.util.Map[Object, Integer]]
          .asScala
          .toMap[Object, Integer]
          .map { case (k, v) => (k.toString, Integer2int(v))}

相反,它将键转换为字符串。


推荐阅读