Исключение Classcast при работе с картой Scala в списке строк - PullRequest
0 голосов
/ 21 июня 2019

У меня есть тип безопасной конфигурации Config, который содержит тип данных карты. Ниже приведено содержимое ключа в файле conf.

test_mapping = {
'15': [8000, 8002],
'5': [500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522],
....
}

Это код, который я использовал для чтения этого ключа из конфига.

scala> val test = config.getObject("test_mapping").asScala map { case (cat, et) => (cat -> et.unwrapped().asInstanceOf[java.util.ArrayList[String]].asScala.toList) }
test: scala.collection.mutable.Map[String,List[String]] = Map('15' -> List(8001, 8002), '5' -> List(500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522), '8' -> List(800, 801, 802, 803, 804), '2' -> List(200, 201, 202, 203, 204, 205...

В приведенном выше коде я понимаю, что я сделал неправильно, файл conf содержит List Ints, но я использовал asInstanceOf для приведения к List [String], но он работает, как видно выше. То, что я не понимаю, это то, почему функция карты на значениях карты терпит неудачу с ClassCastException. Пожалуйста, смотрите код и ошибку ниже.

scala> test.map( { case(c,e) => e.map(identity) } )
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  at scala.collection.immutable.List.map(List.scala:286)
  at .$anonfun$res105$1(<console>:23)
  at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:237)
  at scala.collection.mutable.HashMap.$anonfun$foreach$1(HashMap.scala:149)
  at scala.collection.mutable.HashTable.foreachEntry(HashTable.scala:237)
  at scala.collection.mutable.HashTable.foreachEntry$(HashTable.scala:230)
  at scala.collection.mutable.HashMap.foreachEntry(HashMap.scala:44)
  at scala.collection.mutable.HashMap.foreach(HashMap.scala:149)
  at scala.collection.TraversableLike.map(TraversableLike.scala:237)
  at scala.collection.TraversableLike.map$(TraversableLike.scala:230)
  at scala.collection.AbstractTraversable.map(Traversable.scala:108)
  ... 28 elided

scala>

Это как-то связано с стиранием типов в List [_]? Может кто-нибудь объяснить, почему первая строка, которая преобразуется в List [String], работает, но перебирает ее элементы не удается?

Спасибо!

1 Ответ

0 голосов
/ 23 июня 2019

Ваше предположение о стирании верно.

List[Integer] и List[String] имеют одинаковый тип для JVM во время выполнения. Что означает, что актерский состав фактически ничего не делает во время выполнения. Это шумиха. Но когда вы обращаетесь к отдельным элементам списка, они доступны как String, так как после вашего приведения компилятор «знает», что это List[String].

Теперь JVM фактически проверяет тип, и вы получаете ClassCastException. Это не относится к Scala, оно работает так же в Java (и других типизированных языках JVM).

...