首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

MapReduce 開發必讀:ArrayWritable 正確使用姿勢

     編輯:Java 程式設計入門

在 MapReduce 開發中,若 Map 輸出或 Reduce 輸入涉及數組類型,直接使用 org.apache.hadoop.io.ArrayWritable 會拋出經典異常:

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

根因在於 ArrayWritable 為抽象基類,要求子類在構造時指定數組元素的具體 Writable 類型。官方文檔明確建議:必須創建具體子類並指定元素類型。

標準解決方案:定義強類型子類

以文本數組為例,正確姿勢如下:

import org.apache.hadoop.io.ArrayWritable;
import org.apache.hadoop.io.Text;

public class TextArrayWritable extends ArrayWritable {

    public TextArrayWritable() {
        super(Text.class); // 指定元素類型為 Text
    }

    // 便捷構造:直接從 String[] 轉換
    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); // 設置內部數組
    }
}

核心要點解析

  1. 父類構造必傳 Class<? extends Writable>:告知序列化框架元素類型,否則反序列化時無法實例化元素對象。
  2. 無參構造必須顯式調用 super(ElementClass.class):Hadoop 反射實例化時調用無參構造。
  3. 提供便捷構造/工廠方法:封裝 String[] → Text[] 轉換邏輯,業務代碼更簡潔。
  4. 同類元素約束:ArrayWritable 要求數組內所有元素類型一致,異構數組需自定義封裝類。

實戰場景:Mapper 輸出 String[]

public class LogMapper extends Mapper<LongWritable, Text, Text, TextArrayWritable> {

    @Override
    protected void map(LongWritable key, Text value, Context context) 
            throws IOException, InterruptedException {
        String[] fields = value.toString().split("\t");
        // 業務邏輯處理 fields...
        context.write(new Text(fields[0]), new TextArrayWritable(fields));
    }
}

Reducer 端直接接收 TextArrayWritable,調用 get() 獲取 Writable[],逐元素強轉 Text 即可。

切記:永遠不要直接實例化 ArrayWritable。為每種業務數組類型(Int、Long、Double、自定義 Writable)編寫專用子類,是 MapReduce 類型安全與序列化正確性的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved