Black Rock Blog

Prefer headOption to Head in Scala Collections

| Comments

The List.head() method in Scala’s List collection class provides a simple way to get the first element in the list, but if the list is empty it will throw this exception (since there is nothing it can actually return)

1
2
3
4
5
6
7
val users: List[String] = loadLatestUsers()
val latestUser: String = users.head

java.util.NoSuchElementException: head of empty list
    at scala.collection.immutable.Nil$.head(List.scala:371)
    at scala.collection.immutable.Nil$.head(List.scala:368)
    ...

You can prevent this by checking that the list is non-empty before calling this method. A better (and more Scala-ish) way is to instead call List.headOption() which uses Scala’s Option pattern.

How to handle the case of an empty list depends on your requirements and context, especially what you plan[ned] to do with the first element of the list. If you can defer handling the empty list until the value is used, keep the Option wrapper around the element.

1
val latestUser: Option[String] = users.headOption

Or does an empty list denote a state so broken that you cannot continue?

1
2
3
val latestUser: String = users.headOption.getOrElse {
  throw new RuntimeException("No names are available!") )
}

Does an empty list make the rest of the method simply irrelevant?

1
val latestUser: String = users.headOption.getOrElse( return )

Or can a default, placeholder value be safely used here?

1
val latestUser: String = users.headOption.getOrElse( "" )

After using List.headOption to explicitly handle the case of an empty list, you have now prevented a potential failure at runtime with minimal changes or bulk added to your code.

Comments