-2

I have a scala code snippet given below:

// country code to nameToPlaces traversable
val input : Traversable[(Int, java.util.Map[String, java.util.Set[String]])] ... 
val nameToPlacesMap : Map[String, Set[String]] = input.toMap.
            values.
            map (x => x.toSeq).    // throws a class cast exception
            reduce((x,y) => x ++ y).
            groupBy(_._1).
            mapValues(_.map(_._2).
            reduce((x,y)=>x.toSet ++ y.toSet))

nameToPlacesMap is expected to collate all nameToPlaces from all countries. However, while running this code, i am getting a classcastexception

 java.util.HashMap cannot be cast to scala.collection.immutable.Map

I have tried adding asScala but of no use. I am also importing import scala.collection.JavaConverters._ Any help will be appreciated.

NOTE: I don't see this question as a duplicate of a generic classcast exception as noted below: Please revise your judgement.

Amm Sokun
  • 1,298
  • 4
  • 20
  • 35
  • Your code doesn't compile (too many argument to Traversable). Please edit your post and correct it. Also, it would be useful to know where you put `.asScala`. – The Archetypal Paul Oct 04 '15 at 07:33
  • Try looking at [this](http://stackoverflow.com/questions/3127238/convert-java-util-mapstring-object-to-scala-collection-immutable-mapstring) – Avihoo Mamka Oct 04 '15 at 07:34
  • Is there a special reason why you are mixing Java and Scala collections? If your program is only Scala, then don't use Java collections. – Jesper Oct 04 '15 at 07:45
  • yes because input is obtained from a java api – Amm Sokun Oct 04 '15 at 08:55
  • Could you try `input.flatMap(_._2.asScala).groupBy(_._1).mapValues(_.map(_._2.toSet).reduce(_ ++ _))` ? You need to import both `JavaConversions._` and `JavaConverters._` for that. – Kolmar Oct 04 '15 at 11:23

1 Answers1

0

You have several java collections in your outer map, you have to make sure to convert them all. As far as I can see, the following should work for you:

import java.util

import scala.collection.JavaConverters._
import scala.collection.mutable

val input : Traversable[(Int, java.util.Map[String, java.util.Set[String]])] =
  Seq((1, new util.HashMap[String, java.util.Set[String]]()))

val nameToPlacesMap : Map[String, mutable.Set[String]] = input.toMap.mapValues(
  // convert inner Map
  _.asScala.mapValues(
    // convert java.util.Set
    mutable.Set.empty ++ _.asScala)
  ).values.
            map (x => x.toSeq).    // hopefully not anymore :: throws a class cast exception
            reduce((x,y) => x ++ y).
  groupBy(_._1).
  mapValues(_.map(_._2).
    reduce((x,y)=> x ++ y))
Sascha Kolberg
  • 7,092
  • 1
  • 31
  • 37