zoukankan      html  css  js  c++  java
  • Hadoop 它们的定义Writable NullpointerException

    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);
      }


    通过这段代码能够知道。不一定要通过外部传入。事实上能够从in中读取就可以。详细怎样做呢?定义一个数组distance的大小变量,比方为num。然后把num在write中写入,然后在readFields中先读出,然后再初始化数组distance,这样就不会有刚才的问题了。详细代码例如以下:

    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





    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Discuz 模板语句分析及知识技巧
    phpcms v9添加新模块
    simplexml 对xml的增删改操纵
    phpcms V9 相关阅读/相关文章
    怎么让php生成的网页源代码开头不出现空行
    phpcms v9 如何实现标签的嵌套
    在{pc:content action="lists"标签中加自定义限制条件的办法
    phpcms v9 内容页浏览数不显示问题
    【今日CV 视觉论文速览】29 Nov 2018
    【词云】wordcloud安装与使用
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4719101.html
Copyright © 2011-2022 走看看