我正在使用 Hadoop 0.20.2。我正在编写一个X
实现Writable
.
X
有几个字段是Integer
. 对于这些字段,null
值具有特殊的意义。
序列化对象时,通过在接口DataOutput out
的write
方法中写入Writable
,有没有办法可以写null
?或者我应该使用单独的布尔值来指示值为空?
布尔值是将对象属性标记为NULL
.
考虑这种情况:
public class LongMessage implements Writable {
private long tag;
private String data;
// interface methods omitted first
}
data
可能是这样,null
无论出于何种原因。所以我会按如下方式实现读/写:
@Override
public void readFields(DataInput in) throws IOException {
tag = in.readLong();
if (in.readBoolean()) {
data = in.readUTF();
} else {
data = null;
}
}
@Override
public void write(DataOutput out) throws IOException {
out.writeLong(tag);
if (data != null) {
out.writeBoolean(true);
out.writeUTF(data);
} else {
out.writeBoolean(false);
}
}
它甚至非常易读。但请注意,如 JavaDocs 中所述,每条记录有一个字节的恒定开销#writeBoolean
:
将布尔值写入此输出流。如果参数 v 为真,则写入值(字节)1;如果 v 为假,则写入值(字节)0
NullWritable 是 Writable 的一种特殊类型,因为它具有零长度序列化。没有字节被写入流或从流中读取。如需进一步参考,请查看 hadoop 权威指南 pg:104
序列化时,空对象的大小在Java 对象序列化协议中正好是 1 个字节。write
因此,我认为您的 custom 方法不会有任何问题Writable
。
作为一般规则,这实际上取决于您要建模的内容。如果您尝试表示 aBoolean
并且null表示它不在这里,您可能应该默认为 false。如果它是一个整数,您应该默认为您的数据集的默认值。因此,除非有一些与您提到的“特殊意义”相关的特定处理,否则我认为您可以编写null,否则您应该使用默认值。