Недопонимание конструкторов типа Scala - PullRequest
6 голосов
/ 05 августа 2010

Я пытаюсь написать метод, который берет 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))

1 Ответ

8 голосов
/ 05 августа 2010

Вы случайно создали экзистенциальные типы вместо конструкторов типов.Допустимый конструктор типа будет 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]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...