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
版权声明:本文博客原创文章,博客,未经同意,不得转载。