Использование сбора на картах в Scala

Недавно я наткнулся на этот пост , который «вводит» метод collect для коллекций Scala. Использование простое:

scala> val ints = List(1, "2", 3) collect { case i: Int => i }
ints: List[Int] = List(1, 3)

Теперь карты в основном представляют собой списки пар ключ-значение, которые в Scala представлены кортежами. Так что вы можете попробовать что-то вроде этого:

scala> val pairs = Map(1 -> "I", "II" -> 2)
pairs: scala.collection.immutable.Map[Any,Any] = Map(1 -> I, II -> 2)

scala> val intsToStrings = pairs collect { case pair: (Int, String) => pair }

Компилятор, конечно, жалуется на модель стирания типов JVM, поэтому первое, что мы попробуем, - это использовать экзистенциальные типы:

scala> val intsToStrings = pairs collect { case pair: (_, _) => pair }
intsToString: scala.collection.immutable.Map[Any,Any] = Map(1 -> I, II -> 2)

Хотя код прошел компилятор, и результат "правильный" (нам нужны пары => у нас есть пары), но мы все равно не получили то, что хотели. Вторая попытка выглядит так:

scala> val intsToStrings = pairs collect {
     |    case pair: (_, _) if pair._1.isInstanceOf[Int] && pair._2.isInstanceOf[String] => pair
     | }
intsToStrings: scala.collection.immutable.Map[Any,Any] = Map(1 -> I)

Хорошо, мы почти закончили:

scala> val realIntsToRealStrings = intsToStrings map {
     |    pair => (pair._1.asInstanceOf[Int], pair._2.asInstanceOf[String])
     | }
realIntsToRealStrings: scala.collection.immutable.Map[Int,String] = Map(1 -> I)

Мы сделали это, но вместо преобразования только из (Any, Any) в (Int, String) мы фактически скопировали каждую пару и таким образом создали новую пару.

Теперь перейдем к вопросу. Как я уже упоминал: «Компилятор, конечно, жалуется ...» Я сказал, что действительно знаю, о чем говорю. Я не! Все, что я знаю, это то, что в Java не было дженериков с самого начала. В какой-то момент дженерики вошли в Java, но не в JVM. Таким образом, компилятор проверяет все типы, но как только код запущен, JVM не заботится о параметрическом типе. Он видит только то, что это Карта или Список , но не то, что это Карта [String, Int] или Список [Int] .

Итак, вот мой вопрос.

Со всеми проверками, преобразованием и отображением нам удалось перенести Map [Any, Any] на Map [String, Int] . Есть ли лучший способ сделать это? Я имею в виду, что типы есть, JVM их просто не видит (насколько мне известно) ...

13
задан agilesteel 10 July 2011 в 11:53
поделиться