尝试使用catch表达式来捕获Scala中的ArrayIndexOutOfBoundsException

时间:2015-10-23 11:02:32

标签: scala apache-spark

我有一个源文件,其中包含一些错误的数据记录,我想处理ArrayIndexOutofBoundsException并递增用于输出错误数据记录的累加器。

val test = sourceFile.map(x => x.split("\\|")).
  filter(line => line(0).contains("1017")).map(x => {
    try {
      x.filter(line => {
        line.length >= 37
      }).map(x => x(38))
    }
    catch {
      case x: ArrayIndexOutOfBoundsException => {
        println("Bad Data Found".format(x))
        Linecounter += 1
        None
      }
    }
  })

test.count()
test.saveAsTextFile(Quotepath)
println("Bad Data Count %s:-".format(Linecounter))

问题是我无法将累加器输出视为记录示例1或等等的数量。,任何人都可以帮助不确定这里是否有错误。

2 个答案:

答案 0 :(得分:4)

val xs = (1 to 5).toArray

我们希望通过某个索引从xs获取值,但它可能超出范围。我们将xs从索引提升到部分函数到相应的值

val xsL = xs.lift
xsL: Int => Option[Int] = <function1>

我们现在通过某个索引从xsL获取值,其中out part of index未在partial函数中定义,因此传递None

val res = xs.map( i => xsL(i*2) )
Array[Option[Int]] = Array(Some(3), Some(5), None, None, None)

即指数6810超出范围。

为了收集定义的部分,请考虑

res.flatten
Array[Int] = Array(3, 5)

为了计算出界指数的数量,请考虑

res.count(_ == None)
Int = 3

这种方法避免使用异常捕获和(可变)变量,同时包含所需的所有信息。

答案 1 :(得分:0)

没有必要使用&#39;尝试&#39; &安培; &#39;抓&#39;条款以获得您正在寻找的功能:

val goodLines = sourceFile.map(x => x.split("\\|"))
                          .filter(_(0).contains("1017"))
                          .toSeq //just in case sourceFile is an Iterator

val test = goodLines.filter(_.length > 38)
                    .map(_(38))

val Linecounter = goodLines.count(_.length < 39)