如何检查Spark Row/Schema是否包含指定字段?及字段断言方法问询
场景说明
我们有一个Spark的Row实例:
Row row = ...
在调试会话里可以执行这段代码检查字段是否存在:
row.schema.fieldNamesSet.contains("title") > true
但正式代码里这么写会报错,因为fieldNamesSet是私有成员,无法直接访问:
assertThat(row.schema.fieldNamesSet.contains("title")) // 或者 assertThat(row.schema().fieldNamesSet.contains("title")) // 等等写法都不行 // 这个调用路径不可用,因为成员是"私有访问"权限
问题
- 如何断言Row中不存在指定字段名?
- 如何内联检查Schema是否包含指定字段名?
解决方案
1. 断言Row中不存在指定字段名
先获取Row对应Schema的字段名数组,再判断目标字段是否不在数组中。结合AssertJ断言库的写法:
String[] fieldNames = row.schema().fieldNames(); assertThat(fieldNames).doesNotContain("title");
不用断言库的话,可自行实现判断逻辑:
boolean hasNoTargetField = !Arrays.asList(row.schema().fieldNames()).contains("title"); assert hasNoTargetField : "Row不应包含字段'title'";
2. 内联检查Schema是否包含指定字段名
利用Schema的fieldNames()方法返回的数组,通过两种方式内联判断:
- 转成集合直接判断:
boolean hasTargetField = Arrays.asList(row.schema().fieldNames()).contains("title");
- 用Stream流操作(Java 8+):
boolean hasTargetField = Arrays.stream(row.schema().fieldNames()).anyMatch("title"::equals);
如果要直接写在断言里:
assertThat(Arrays.stream(row.schema().fieldNames()).anyMatch("title"::equals)).isTrue(); // 或用AssertJ更简洁的写法 assertThat(row.schema().fieldNames()).contains("title");
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

