arrayindexoutofboundsexception

vaqhlq81  于 2021-06-02  发布在  Hadoop
关注(0)|答案(2)|浏览(513)

我要走了 ArrayIndexOutofBoundsException 旁边 String temp = word[5]; 在我的Map。
我已经对此进行了研究,我知道错误来自何处(当输入数据为空或长度小于或大于代码中指定的索引时)。我的数据有一些空单元格值)
我试图用下面的代码捕捉数组索引错误,但它仍然给我错误。

import java.io.IOException;
import java.util.*;

import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;

public class AvgMaxTempMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, DoubleWritable> {

  public void map(LongWritable key, Text value, OutputCollector<Text, DoubleWritable> output, Reporter reporter) throws IOException {

    String line = value.toString();

    if(line != null && !line.isEmpty() && str.matches(".*\\d+.*"));
        String [] word = line.split(",");
        String month = word[3];
        String temp = word[5];
        if (temp.length() > 1 && temp.length() < 5){
            Double avgtemp = Double.parseDouble(temp);

        output.collect(new Text(month),  new DoubleWritable(avgtemp));
    }
  }
}

如果你能给我一些提示或提示,告诉我错误是在这段代码中,还是我应该去别的地方看看,那将节省很多压力!

iyzzxitl

iyzzxitl1#

通过在方法签名中抛出异常,您基本上会导致整个Map程序在遇到单个“坏”数据行时停止。实际上,您要做的是让Map器忽略该行数据,但继续处理其他行。
你应该检查一下 word[] 紧接着 split() . 如果不够长,请停止处理该行。你还需要检查一下 month 以及 temp 提取后有效。怎么样:

String [] word = line.split(",");
if (word == null || word.length < 6) {
    break;
}

String month = word[3];
if (month != null) {
    break;
}

String temp = word[5];

if (temp != null && temp.length() > 1 && temp.length() < 5) {
    try {
        Double avgtemp = Double.parseDouble(temp);
    } catch (NumberFormatException ex) {
        //Log that you've seen a dodgy temperature
        break;
    }
    output.collect(new Text(month), new DoubleWritable(avgtemp));
}

在mapreduce作业中验证数据是非常重要的,因为您永远无法保证您将得到什么作为输入。
你也可以看看apachecommons StringUtils 以及 ArrayUtils 类-它们提供如下方法 StringUtils.isEmpty(temp) 以及 ArrayUtils.isEmpty(word) 那会把上面的东西整理干净的。

ryevplcw

ryevplcw2#

我建议改用自定义计数器,每次找到空单元格时,计数器都会增加。这将为您提供数据中存在多少这样的行的图片。除其他一些效率改进外,我的建议如下:

import java.io.IOException;  //do you still need this?
import java.util.*;

import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;

public class AvgMaxTempMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, DoubleWritable> {

  public static enum STATS {MISSING_VALUE};
  private Text outKey = new Text();
  private DoubleWritable outValue = new DoubleWritable();      

  public void map(LongWritable key, Text value, OutputCollector<Text, DoubleWritable> output, Reporter reporter) throws IOException {

    String line = value.toString();

    if(line.matches(".*\\d+.*"));
        String [] word = line.split(",");
        if (word.length < 6) { //or whatever else you consider expected
            reporter.incrCounter(STATS.MISSING_VALUE,1); //you can also print/log an error message if you like                
            return;
        }
        String month = word[3];
        String temp = word[5];
        if (temp.length() > 1 && temp.length() < 5){
            Double avgtemp = Double.parseDouble(temp);                  
            outKey.set(month);
            outValue.set(avgtemp);
            output.collect(outKey, outValue);
        } //you were missing this '}'
    }
  }

}

相关问题