雖然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