2010-08-04 57 views
6

我想写一个方法,它需要一个Map [K,Collection [V]]并将其转换为具有不同类型Collection的地图。该方法采用“multimap”和将构建新集合的构建器。我用这样的:斯卡拉类型的构造函数误解

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) 

这里的建设者的样子:

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] 
    } 
} 

这里的asMap的实现()。它的工作原理,但我不明白 - 为什么我需要最后的类型演员?

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 
} 

没有类型情况下,我得到这个错误:

[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)) 

回答

8

您无意中创建存在的类型而不是类型构造。一个有效的类型构造函数会C[X] <: Collection[X|所以你需要改变Builder

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

asMap

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