You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Hadoop MapReduce映射阶段NullPointerException异常排查求助

排查MapReduce程序中的空指针异常

看起来你遇到的空指针异常和几个代码逻辑问题有关,我来帮你一步步拆解和修复:

1. 直接触发空指针的元凶:错误使用Integer.getInteger()

你在map方法里用了Integer.getInteger(campi[0]),但这个方法根本不是用来将字符串转整数的!它的作用是读取JVM的系统属性(比如Integer.getInteger("java.version")),如果传入的字符串不是系统属性名,会直接返回null。当你用null做数值比较时,自然会抛出NullPointerException

正确的字符串转整数方法是Integer.parseInt(String),它能把合法的数字字符串转换成int值。

2. 输入数据结构理解错误(核心逻辑问题)

从你的输入输出示例来看,输入是用分号分隔的多条边,每条边是两个数字用空格分隔(比如3 2表示边(3,2)),但你原来的代码直接把整行按分号分割后就当成了边的两个顶点,这完全不符合输入格式!

正确的处理逻辑应该是:

  • 先把整行按;分割,得到单个边的字符串(比如"1", "3 2", "1 0"
  • 再对每个边字符串按空格分割,提取出两个顶点(只有分割后长度为2的才是有效边)

3. 字符串拼接的API错误

你原来的代码里写了:

context.write(new Text(campi[1]+";")+campi[0], NullWritable.get());

这里new Text(...)是一个Text对象,和字符串相加会自动转成String类型,但context.write要求第一个参数是Text类型,虽然编译能过,但这不符合MapReduce的API规范,应该直接构造正确的Text对象。

修复后的完整Mapper代码

结合上面的问题,修复后的Mapper应该是这样的:

public static class MyMapper extends Mapper<LongWritable, Text, Text, NullWritable> {
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString().trim();
        // 跳过空行
        if (line.isEmpty()) {
            return;
        }
        // 第一步:按分号分割所有边的字符串
        String[] edgeStrings = line.split(";");
        for (String edgeStr : edgeStrings) {
            edgeStr = edgeStr.trim();
            if (edgeStr.isEmpty()) {
                continue;
            }
            // 第二步:按空格分割边的两个顶点(支持多个空格分隔)
            String[] vertices = edgeStr.split("\\s+");
            if (vertices.length == 2) {
                try {
                    int x = Integer.parseInt(vertices[0].trim());
                    int y = Integer.parseInt(vertices[1].trim());
                    Text outputKey;
                    // 调整边的顺序,保证x<=y
                    if (x > y) {
                        outputKey = new Text(y + " " + x);
                    } else {
                        outputKey = new Text(x + " " + y);
                    }
                    context.write(outputKey, NullWritable.get());
                } catch (NumberFormatException e) {
                    // 捕获非数字输入的情况,打印日志后跳过
                    System.err.println("跳过无效边:" + edgeStr + ",错误信息:" + e.getMessage());
                }
            }
            // 单个数字的无效数据直接跳过
        }
    }
}

额外的小优化

  • 增加了trim()处理,避免输入中的空格干扰
  • 加入了异常捕获,防止非数字输入导致任务崩溃
  • \\s+分割顶点,支持多个空格分隔的情况

你的Reducer逻辑是对的,因为Reducer会自动对相同的Key去重,直接输出每个Key一次就能得到无重复的边。

修复后重新打包运行,应该就能解决空指针异常,同时正确处理输入数据了。

内容的提问来源于stack exchange,提问作者user9516512

火山引擎 最新活动