scalacollectionsdictionaryscala-java-interop

Getting a Scala Map from a Java Properties


I was trying to pull environment variables into a scala script using java Iterators and / or Enumerations and realised that Dr Frankenstein might claim parentage, so I hacked the following from the ugly tree instead:

import java.util.Map.Entry
import System._

val propSet = getProperties().entrySet().toArray()
val props   = (0 until propSet.size).foldLeft(Map[String, String]()){(m, i) =>
  val e = propSet(i).asInstanceOf[Entry[String, String]]
  m + (e.getKey() -> e.getValue())
}

For example to print the said same environment

props.keySet.toList.sortWith(_ < _).foreach{k =>
  println(k+(" " * (30 - k.length))+" = "+props(k))
}

Please, please don't set about polishing this t$#d, just show me the scala gem that I'm convinced exists for this situation (i.e java Properties --> scala.Map), thanks in advance ;@)


Solution

  • Scala 2.7:

    val props = Map() ++ scala.collection.jcl.Conversions.convertMap(System.getProperties).elements
    

    Though that needs some typecasting. Let me work on it a bit more.

    val props = Map() ++ scala.collection.jcl.Conversions.convertMap(System.getProperties).elements.asInstanceOf[Iterator[(String, String)]]
    

    Ok, that was easy. Let me work on 2.8 now...

    import scala.collection.JavaConversions.asMap
    val props = System.getProperties() : scala.collection.mutable.Map[AnyRef, AnyRef] // or
    val props = System.getProperties().asInstanceOf[java.util.Map[String, String]] : scala.collection.mutable.Map[String, String] // way too many repetitions of types
    val props = asMap(System.getProperties().asInstanceOf[java.util.Map[String, String]])
    

    The verbosity, of course, can be decreased with a couple of imports. First of all, note that Map will be a mutable map on 2.8. On the bright side, if you convert back the map, you'll get the original object.

    Now, I have no clue why Properties implements Map<Object, Object>, given that the javadocs clearly state that key and value are String, but there you go. Having to typecast this makes the implicit option much less attractive. This being the case, the alternative is the most concise of them.

    EDIT

    Scala 2.8 just acquired an implicit conversion from Properties to mutable.Map[String,String], which makes most of that code moot.