In tests, I'm trying to convert dataframe/datasets into sets and compare it. E.g.
actualResult.collect.toSet should be(expectedResult.collect.toSet)
I noticed some facts regarding Double.NaN value.
- In Scala,
Double.NaN == Double.NaNreturns false. - In spark
NaN == NaNis true. (offical doc)
But I couldn't figure out why dataframe and dataset behaves differently.
import org.apache.spark.sql.SparkSession
object Main extends App {
val spark = SparkSession.builder().appName("Example").master("local").getOrCreate()
import spark.implicits._
val dataSet = spark.createDataset(Seq(Book("book 1", Double.NaN)))
// Compare Set(Book(book 1,NaN)) to itself
println(dataSet.collect.toSet == dataSet.collect.toSet) //false, why?
// Compare Set([book 1,NaN]) to itself
println(dataSet.toDF().collect.toSet == dataSet.toDF().collect.toSet) //true, why?
}
case class Book (title: String, price: Double)
Here's my question. Appreciate any insights.
- How does it happen in code? (where the
equalsgets overridden? etc..) - Any reasons behind this design? Is there a better paradigm to assert dataset/dataframe in tests?