Manu Chadha
Manu Chadha

Reputation: 16755

companion method in List

I notice a method called 'companion' in List class. What does it do? Its definition is 'The factory companion object that builds instances of class List.'

It seems I can create new instances of a List using l.companion(11,12,13) method but why would I do it this way instead of using List(11,12,13)?

val l = List[Int](1,2,3,4,1)
l: List[Int] = List(1, 2, 3, 4, 1)

val l2 = l.companion
l2: scala.collection.generic.GenericCompanion[List] = scala.collection.immutable.List$@6c3e1f48

//I can create new instances of a List using l2 but why would I do it this way?
val l3 = l2(100,11,123)

l3.foreach(println _)
100
11
123
res0: Unit = ()

The object returned from companion can also be used to create mutable collections (Builders). But why would I create collection this way!

//create a Builder (a mutable collection) whose elements would be list of strings
val l5 = l2.newBuilder[List[String]]
l5: scala.collection.mutable.Builder[List[String],List[List[String]]] = ListBuffer()

l5+=List("h")
l5+=List("2")

println(l5)
ListBuffer(List(h), List(2))
res3: Unit = ()

Upvotes: 1

Views: 335

Answers (1)

Michael Zajac
Michael Zajac

Reputation: 55569

It's not really meant for you to use in normal circumstances. Many companion objects of collection classes inherit from GenericCompanion. Anything that inherits from it must implement newBuilder, which provides a Builder for the associated collection type. In turn, that collection's companion object inherits the apply and empty methods, which are used virtually everywhere in the standard collections library.

The (likely) reason every List (and many other collections) has a reference to it's own companion is so that it can be used for generics, particularly with higher-kinds.

There is no native way to connect a type with its companion using the type system alone. For example, if you want some M[A] <: Traversable[A], you have no way of finding it's companion (in general, a generic type like this might not even have one). To work around this, we require that the collection itself has a reference to it's own companion (with other type parameters and constraints imposed). It also saves the need to have multiple implementations of apply and empty copied throughout all of the collections.

Upvotes: 1

Related Questions