Hadoop周边环境:Hadoop2.4
定义中的Hadoop的Writable时间,有时你需要使用数组,而不是简单的单一值或串。例如,下面的代码:
package test; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import org.apache.hadoop.io.WritableComparable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyData implements WritableComparable<MyData>,Cloneable { private Logger log = LoggerFactory.getLogger(MyData.class); private float[] distance; public MyData(){// 空指针异常 set(new float[6]); // 凝视掉此行代码,在readFields会有空指针异常 } public MyData(float[] distance) { set(distance); } public void set(float[] distance) { this.distance=distance; } @Override public void readFields(DataInput arg0) throws IOException { for(int i=0;i<distance.length;i++){ distance[i]=arg0.readFloat(); } } @Override public void write(DataOutput arg0) throws IOException { for(int i=0;i<distance.length;i++){ arg0.writeFloat(distance[i]); } } @Override public int compareTo(MyData o) {// 当前值小于o则返回负数 float[] oDistance =o.distance; int cmp=0; for(int i=0;i<oDistance.length;i++){ if(Math.abs(this.distance[i]-oDistance[i])<0.0000000001){ continue; // 比較下一个 } if(this.distance[i]<oDistance[i]){ return -1; }else{ return 1; } } return cmp; } @Override public int hashCode(){ int hashCode =0; for(int i=0;i<distance.length;i++){ hashCode=+Float.floatToIntBits(distance[i]); } return hashCode; } public float[] getDistance() { return distance; } public void setDistance(float[] distance) { this.distance = distance; } }能够看到其无參构造函数里面含有一个初始化的操作。这个初始化的操作限定了其矩阵distance的维度(代码中设置为6),可是一般这个值由外部设置才比較合适,可是在读取的时候,也就是readFields的时候是从这个无參构造函数进入的,这里没有办法设置參数,没有办法在外面初始化这个矩阵的大小,可是不设置又不行。有没有什么办法呢?在Mahout的一些代码中能够看到相似的代码。比方VectorWritable,从VectorWritable能够找到解决问题的答案。
先看看vectorWritable的一段代码:
@Override public void readFields(DataInput in) throws IOException { int flags = in.readByte(); int size = Varint.readUnsignedVarInt(in); readFields(in, (byte) flags, size); }
package test; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import org.apache.hadoop.io.WritableComparable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyData implements WritableComparable<MyData>,Cloneable { private Logger log = LoggerFactory.getLogger(MyData.class); private float[] distance; private int num; public MyData(){// 此处不再有空指针异常 // set(new float[6]); // 凝视掉此行代码,在readFields不会有空指针异常 } public MyData(float[] distance) { this.num=distance.length; set(distance); } public void set(float[] distance) { this.distance=distance; } @Override public void readFields(DataInput arg0) throws IOException { num = arg0.readInt(); distance = new float[num]; for(int i=0;i<distance.length;i++){ distance[i]=arg0.readFloat(); } } @Override public void write(DataOutput arg0) throws IOException { arg0.writeInt(num); for(int i=0;i<distance.length;i++){ arg0.writeFloat(distance[i]); } } @Override public int compareTo(MyData o) {// 当前值小于o则返回负数 float[] oDistance =o.distance; int cmp=0; for(int i=0;i<oDistance.length;i++){ if(Math.abs(this.distance[i]-oDistance[i])<0.0000000001){ continue; // 比較下一个 } if(this.distance[i]<oDistance[i]){ return -1; }else{ return 1; } } return cmp; } @Override public int hashCode(){ int hashCode =0; for(int i=0;i<distance.length;i++){ hashCode=+Float.floatToIntBits(distance[i]); } return hashCode; } public float[] getDistance() { return distance; } public void setDistance(float[] distance) { this.distance = distance; } }
通过上面的改进,就不用操心 空指针的问题了。
分享。成长,快乐
转载请注明blog地址:http://blog.csdn.net/fansy1990
版权声明:本文博客原创文章,博客,未经同意,不得转载。