Подтвердить что ты не робот

Получение карты Scala из свойств Java

Я пытался перетащить переменные окружения в scala script с помощью java Iterators и/или Enumerations и понял, что Dr Frankenstein может требовать отцовство, поэтому вместо этого я взломал следующее из уродливого дерева:

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())
}

Например, для печати указанной среды

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

Пожалуйста, не задавайте вопрос о полировке этого t $# d, просто покажите мне драгоценный камень scala, который, я уверен, существует для этой ситуации (например, java Properties → scala.Map), спасибо заранее; @)

4b9b3361

Ответ 1

Scala 2.7:

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

Хотя для этого требуется некоторое приведение типов. Позвольте мне немного поработать над этим.

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

Хорошо, это было легко. Позвольте мне теперь работать над 2.8...

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]])

Многословие, конечно же, может быть уменьшено с помощью нескольких импортных товаров. Прежде всего, обратите внимание, что Map будет изменчивым отображением на 2.8. С яркой стороны, если вы перевернете карту назад, вы получите исходный объект.

Теперь я не знаю, почему Properties реализует Map<Object, Object>, учитывая, что javadocs четко заявляет, что ключ и значение String, но там вы идете. Имея в виду, это делает неявный вариант гораздо менее привлекательным. В этом случае альтернатива является наиболее кратким из них.

ИЗМЕНИТЬ

Scala 2.8 только что получил неявное преобразование от Properties до mutable.Map[String,String], что делает большую часть этого кода спорным.

Ответ 2

В Scala 2.9.1 это решается неявными преобразованиями внутри collection.JavaConversions._. Другие ответы используют устаревшие функции. Подробности описаны здесь. Это соответствующий фрагмент из этой страницы:

scala> import collection.JavaConversions._  
import collection.JavaConversions._

scala> import collection.mutable._
import collection.mutable._
scala> val jul: java.util.List[Int] = ArrayBuffer(1, 2, 3)
jul: java.util.List[Int] = [1, 2, 3]
scala> val buf: Seq[Int] = jul
buf: scala.collection.mutable.Seq[Int] = ArrayBuffer(1, 2, 3)
scala> val m: java.util.Map[String, Int] = HashMap("abc" -> 1, "hello" -> 2)
m: java.util.Map[String,Int] = {hello=2, abc=1} 

Переход с измененной карты на неизменяемую карту - это вопрос вызова toMap на ней.

Ответ 3

В Scala 2.8.1 вы можете сделать это с помощью asScalaMap(m : java.util.Map[A, B]) более сжатым способом:

var props = asScalaMap(System.getProperties())

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

Ответ 4

Scala 2.10.3

import scala.collection.JavaConverters._

//Create a variable to store the properties in
val props = new Properties

//Open a file stream to read the file
val fileStream = new FileInputStream(new File(fileName))
props.load(fileStream)
fileStream.close()

//Print the contents of the properties file as a map
println(props.asScala.toMap)

Ответ 5

Похоже, что в последней версии Scala (2.10.2 на момент ответа) предпочтительный способ сделать это - использовать явный .asScala from scala.collection.JavaConverters:

import scala.collection.JavaConverters._

val props = System.getProperties().asScala

assert(props.isInstanceOf[Map[String, String]])