Reputation: 16755
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
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