2010-08-04 10 views
6

Estoy tratando de escribir un método que toma un Mapa [K, Colección [V]] y lo convierte en un mapa con un tipo diferente de Colección para sus valores. El método toma el "multimap" y un constructor que construirá las nuevas colecciones. Yo lo uso como esto:Scala type malentendido de constructores

val multimap = new java.util.HashMap[Int, java.util.List[String]] 
multimap.put(1, Arrays.asList("One")) 
multimap.put(2, Arrays.asList("Two", "Three")) 

val mapOfLists: java.util.Map[Int, java.util.Set[String]] = 
    asMap(multimap, Builder.SET) 

Esto es lo que se ve como el constructor:

trait Builder[C[_] <: java.util.Collection[_]] 
{ 
    def create[V]: C[V] 
} 

object Builder 
{ 
    val SET = new Builder[java.util.Set]() 
    { 
     def create[V]: java.util.Set[V] = new java.util.HashSet[V] 
    } 
} 

Aquí está la implementación de ASMAP(). Funciona, pero no entiendo - ¿por qué necesito el tipo de molde al final?

def asMap[K, V, C[_] <: java.util.Collection[_]](
     multimap: java.util.Map[K, _ <: java.util.Collection[V]], builder: Builder[C]): java.util.Map[K, C[V]] = 
{ 
    val result = new java.util.HashMap[K, C[V]] 
    val iterator: Iterator[K] = multimap.keySet.iterator 
    while (iterator.hasNext) 
    { 
     val key = iterator.next 
     val collection: C[V] = builder.create[V] 
     collection.asInstanceOf[java.util.Collection[V]].addAll(multimap.get(key)) 
     result.put(key, collection) 
    } 
    result 
} 

Sin el tipo caso me sale este error:

[ERROR] error: type mismatch; 
[INFO] found : java.util.Collection[V] 
[INFO] required: java.util.Collection[_ <: _$2] where type _$2 
[INFO]    collection.addAll(multimap.get(key)) 

Respuesta

8

Ha creado accidentalmente tipos existenciales en lugar de constructores de tipos. Un constructor de tipo válida sería C[X] <: Collection[X| por lo que necesita para cambiar Builder a

trait Builder[C[X] <: Collection[X]] { 
    def create[V]: C[V] 
} 

y la firma de asMap a

def asMap[K, V, C[X] <: Collection[X]](multimap: Map[K, _ <: Collection[V]], 
    builder: Builder[C]): Map[K, C[V]] 
Cuestiones relacionadas