Hadoop 中的 ArrayWritable


雖然ArrayWritable不是接口,但貌似必須要子類去extends ArrayWritable,不能直接用ArrayWriable

 否則會報下面的錯誤?(不是很確定)

java.lang.Exception: java.lang.RuntimeException: java.lang.NoSuchMethodException: org.apache.hadoop.io.ArrayWritable.<init>()

  

下面是我自己實現的ArrayWritable,完全是自己摸索的網上看到的幾篇感覺都不是很靠譜

 

這個是為了Reduce輸出結果中包含一個list,我研究一個晚上的時間,才把它弄好,結果后來發現標准答案,是用StringBuffer把list中的每個元素一個一個append然后輸出的……  

這樣真的簡化了太多的代碼,而且實現難度變得低了不少。看來寫代碼還是要多動腦子。

 

不過唯一的好處是研究了一下ArrayWritable的源碼,同時自己實現了這個父類,也算是有所收獲

 

 

import org.apache.hadoop.io.ArrayWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableFactories;
/**
 * 自己實現ArrayWritable類,直接用好像會出問題
 * @author wmxl
 *
 */
class TextArrayWritable extends ArrayWritable {
    
    //父類其實有一個private的value,可以直接用那個,具體看ArrayWritable源碼
    private Text[] myValue = new Text[0];
    
    public Text[] getMyValue() {
        
        return myValue;
    }

    public void setMyValue(Text[] myValue) {
        this.myValue = myValue;
    }

    //這兩個構造方法一定要實現TextArrayWritable() 和 TextArrayWritable(String[] strings) 而且里面要寫super(Text.class)
    public TextArrayWritable() {
         super(Text.class);
    }
    
    public TextArrayWritable(String[] strings) {
        
        super(Text.class);
        Text[] texts = new Text[strings.length];
        
        for (int i = 0; i < strings.length; i++) {
            texts[i] = new Text(strings[i]);
        }
//        set(texts);  //這個是set父類的value
        setMyValue(texts);
    }

    @Override
      public void readFields(DataInput in) throws IOException {  //這兩個方法都是copy父類的,稍作改動,看的不是很懂
        myValue = new Text[in.readInt()];          // construct values
        for (int i = 0; i < myValue.length; i++) {
          Text value = (Text) WritableFactories.newInstance(Text.class);
          value.readFields(in);                       // read a value
          myValue[i] = value;                          // store it in values
        }
      }

      @Override
      public void write(DataOutput out) throws IOException {    //同上
        out.writeInt(myValue.length);                 // write values
        for (int i = 0; i < myValue.length; i++) {
            myValue[i].write(out);
        }
      }
      
    
    /**
     * 重寫這個方法,讓最后write文件中的結果是你想要的樣子
     */
    @Override
    public String toString() {
        
        StringBuffer result = new StringBuffer();
        
        for(int i =0; i < this.getMyValue().length; i++){
            if(i == this.getMyValue().length -1)
                result.append(this.getMyValue()[i].toString());
            else
                result.append(this.getMyValue()[i].toString()).append(",");
        }
        
        return result.toString();
    }
    
    public void add(String friend){
        int len = getMyValue().length;
        Text[] newValue = new Text[len + 1];
        for(int i = 0; i < len + 1; i++){
            if(i < len)
                newValue[i] = getMyValue()[i];
            else
                newValue[i] = new Text(friend);
        }

        myValue = newValue;
    }
    /**
     * 自己寫的添加元素方法
     * @param friend
     */
    public void add(Text friend){  
        int len = getMyValue().length;
        Text[] newValue = new Text[len + 1];
        for(int i = 0; i < len + 1; i++){
            if(i < len)
                newValue[i] = getMyValue()[i];
            else
                newValue[i] = new Text(friend);
        }

        myValue = newValue;
    }
}

參考了這篇文章:https://www.cnblogs.com/yancey/p/3946513.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM