2

I am a new developper on Scala and I want to write a simple function :

def compute_start(start: Option[Long]) : (Int, Int, Int) = {
    if (start != null.asInstanceOf[Long] && start != null && start != "null") { // I tried ALL THOSE OPTIONS !!!
        var result = helper(start.get) // another function
        (temp._1, temp._2, temp._3)
    } else {
        (0, 0, 0)
    }

But I always get this error :

org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 696.0 failed 8 times, most recent failure: Lost task 0.7 in stage 696.0 (TID 99422, ldatanode10ch.nms.ld, executor 145): java.util.NoSuchElementException: None.get

So, I guess that the condition if (start != null.asInstanceOf[Long] didn't return true.

Please, how can I avoid a null values for a long (or Option[long] ) variable ?? Thank you !

salamanka44
  • 904
  • 3
  • 17
  • 36
  • 2
    `null.asInstanceOf[Long]` is always 0 so the condition never holds if `start != 0` Also see: https://stackoverflow.com/a/39210959/2928853 – jrook Nov 26 '19 at 17:37

4 Answers4

2

You can use pattern matching like this:

def compute_start(start: Option[Long]) : (Int, Int, Int) = {
  start match {
     case Some(value) => 
       val result = helper(value)
       (result._1, result._2, result._3)
     case None => (0,0,0)
  }

}

Edit:
Thinking a little bit more about your issue, I believe your start value is being passed as null which is a side-effect from some strange Java library that is passing this value down to your function.
One way to deal with it is to ensure an Optional value like this:

// simulated value got from your library (must probably)
val start: Option[Long] = null

// ensure the start value is safe (without null values)
val safeStart = Option(start).filter(_.nonEmpty).flatten

// Now you should get a safe result
val result = compute_start(start)
Bruno Paulino
  • 5,611
  • 1
  • 41
  • 40
1

Wrap the null (Option(x)), then unwrap it (.flatten), then proceed as a standard Option[Long].

def compute_start(start: Option[Long]) : (Int, Int, Int) =
  Option(start).flatten.fold((0, 0, 0)){ startVal =>
    val result = helper(startVal) // don't use var's
    (temp._1, temp._2, temp._3)
  }
jwvh
  • 50,871
  • 7
  • 38
  • 64
0

You can pattern match on start to safely test whether or not start has a value and extract it into a variable(long) then use it the same way you would in your if statement.

def compute_start(start: Option[Long]) : (Int, Int, Int) = start match {
  case Some(long) => {
    var result = helper(long) // another function
    (temp._1, temp._2, temp._3)
  }
  case None    => (0,0,0)
}
Brian
  • 20,195
  • 6
  • 34
  • 55
0

Your error is NoSuchElementException, not a NullPointerException. In particular, the error message

java.util.NoSuchElementException: None.get

means you are calling get on a None, probably in this line (but you should see from the stack trace):

var result = helper(start.get)

Of course, if start is None, then it isn't equal to 0L (the result of 0.asInstanceOf[Long]), null, or "null" and so none of your checks work.

So to fix that you should pattern-match as other answers said. If in that case you get NullPointerException and it still comes from this place, my guess would be that start is Some(null). You can handle it e.g. like this

def compute_start(start: Option[Long]) : (Int, Int, Int) = {
  start match {
     case Some(value) if value != null => 
       val result = helper(value)
       (result._1, result._2, result._3)
     case _ => (0,0,0)
  }

}

Case _ covers anything not matched by previous cases including Some(null) and null.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487