There are 2 ways to get the first element of a random-access Scala collection (e.g. Vector):
1) head
myCollction.head 2) apply
myCollction(0) From what I gathered (from Scala 2.10.4 sources)
head first checks if the collection is empty and throws an exception before calling apply(0)
override /*IterableLike*/ def head: A = { if (isEmpty) throw new UnsupportedOperationException("empty.head") apply(0) }apply first checks the bounds of the index and throws IndexOutOfBoundsException before getting the element
def apply(index: Int): A = { val idx = checkRangeConvert(index) getElem(idx, idx ^ focus) } private def checkRangeConvert(index: Int) = { val idx = index + startIndex if (0 <= index && idx < endIndex) idx else throw new IndexOutOfBoundsException(index.toString) }
What is the preferred way ? (actual benefits / pitfalls, not personal preference)
2 Answers
use .headOption
Usually preferred way is (but it depends on the context)
myCollection.headOption .headOption returns Option value where option is Some when head is present and it is none if the collection is empty.
Using headOption does not throw exception is the collection is empty hence you do not have any unexpected surprises.
Both .head and zero index throw exceptions when the underlying collection is empty.
It also depends on the context, if you want to fail if head element is not present then .head is a good way to do that, but it many cases you want to provide an alternative if collection does not have any elements in it
I think the most idiomatic way to select the first element of any collection, including a random-access collection such as Vector, would be to use the headOption method which returns None in the case that an exception would be thrown. Benefits of this approach would be that the caller can pattern-match on headOption and respond appropriately.