Scala中遍历org.apache.avro.Schema并检测null类型的方法
解决Avro联合Schema遍历与null类型检测问题
嘿,我来帮你搞定这个问题!你遇到的报错其实很好理解:org.apache.avro.Schema本身并不是可迭代的集合类型,直接用for循环遍历它当然会失败。从你的输出schema:["null","string"]能看出来,这个Schema是Avro联合类型(Union Schema),要处理这种类型,得先拿到它的子类型列表才行。
下面是具体的实现步骤和代码:
步骤1:判断当前Schema是否为联合类型
Avro的Schema有多种类型(比如UNION、STRING、NULL等),我们首先要确认当前的Schema是联合类型,才能获取它的子类型:
import org.apache.avro.Schema // 先判断是否是联合类型 if (schema.getType == Schema.Type.UNION) { // 后续处理逻辑写在这里 }
步骤2:获取并遍历联合类型的子Schema
联合类型的Schema提供了getTypes()方法,它会返回一个java.util.List[Schema],我们可以把它转换成Scala的可迭代集合来处理:
import scala.collection.JavaConverters._ // 适配Scala 2.12及之前版本,Scala 2.13+可直接用java.util.List#asScala if (schema.getType == Schema.Type.UNION) { // 将Java List转为Scala可迭代集合 val subSchemas = schema.getTypes.asScala // 遍历子Schema并打印类型 for (subSchema <- subSchemas) { println(s"子Schema类型: ${subSchema.getType}") } }
步骤3:高效检测是否存在null类型
如果只是想检查是否至少存在一个null类型,不用全遍历,直接用exists方法更高效:
import org.apache.avro.Schema import scala.collection.JavaConverters._ val hasNullType = schema.getType == Schema.Type.UNION && schema.getTypes.asScala.exists(_.getType == Schema.Type.NULL) println(s"是否包含null类型: $hasNullType") // 你的示例中会输出true
完整示例代码
把这些逻辑整合起来,完整的可运行代码如下:
import org.apache.avro.Schema import scala.collection.JavaConverters._ import scala.reflect.runtime.universe._ def getType[T: TypeTag](value: T) = typeOf[T] // 假设你的schema变量已经初始化完成 println(getType(schema)) // 输出: org.apache.avro.Schema println("schema:" + schema) // 输出: schema:["null","string"] // 检测是否存在null类型 val hasNullType = schema.getType == Schema.Type.UNION && schema.getTypes.asScala.exists(_.getType == Schema.Type.NULL) println(s"该联合Schema是否包含null类型: $hasNullType")
核心思路就是:别直接遍历顶层的Schema对象,先识别它是联合类型,再操作它的子类型列表,这样就能顺利实现你的需求啦。
内容的提问来源于stack exchange,提问作者user9750148
相关产品推荐
相关产品推荐

