【问题标题】:Getting a Scala Map from a Java Properties从 Java 属性获取 Scala 映射
【发布时间】:2011-01-02 05:49:35
【问题描述】:

我试图使用 java Iterators 和/或 Enumerations 将环境变量拉入 scala 脚本,并意识到 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 gem(即 java Properties --> scala.Map),在此先感谢 ;@ )

【问题讨论】:

  • 不,Ruby 对我来说太酷了,我猜是书架上的 Stan Lippman 的 C++ Gems 副本引起了我的注意。

标签: scala collections map scala-java-interop


【解决方案1】:

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)

【讨论】:

  • 嗨,萨拉特。感谢您为本网站做出贡献。我们更喜欢 StackOverflow 上的答案,以便有更多的解释,而不仅仅是发布代码。尝试阅读此guide to posting good answers 以获得更多帮助:)
【解决方案2】:

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&lt;Object, Object&gt;,因为 javadocs 明确指出键和值是 String,但你去吧。必须对 this 进行类型转换使得隐式选项的吸引力大大降低。在这种情况下,替代方案是其中最简洁的。

编辑

Scala 2.8 刚刚获得了从 Propertiesmutable.Map[String,String] 的隐式转换,这使得大部分代码没有意义。

【讨论】:

  • 附带说明,这是我第一次进行 Java Scala 集合转换。我最后一次尝试时经验不足,无法使其正常工作。而且我不仅有机会克服之前的失败,而且我发现这个特别的问题非常有趣,因为我发现自己不时会仔细阅读系统属性!
  • 谢谢丹尼尔,稍后我会仔细查看您的答案。我很高兴激起了您对这个话题的兴趣。
  • @Daniel,我怀疑这是我正在寻找的宝石,只是对演员阵容感到遗憾,特别是因为属性应该实现 Map[String, String]。这些转化对我来说是一个很好的发现。
  • 澄清一下,强制转换是 Java 对 Properties 错误的实现,而不是 Scala 的错误。
  • Daniel,混沌善良精灵法师击败了 Java Properties 构造的古老、粗糙、邪恶的野兽。抱歉,但你的第一条评论让我想起了 RPG……
【解决方案3】:

在 Scala 2.9.1 中,这是通过 collection.JavaConversions._ 中的隐式转换来解决的。其他答案使用不推荐使用的功能。详细信息记录在here。这是该页面中的相关 sn-p:

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。

【讨论】:

  • 感谢您的更新,丹尼尔确实对他的回答进行了编辑,提到了这些隐含的内容。具有讽刺意味的是,在 scala 2.10 中访问环境将更加直接,只需使用 sys.env 方法返回的不可变映射。
  • 刚刚意识到这是将属性转换为我要求的 Scala 映射,但是 Scala 2.10 也有一个 sys.props 方法来访问系统属性。
  • 丹尼尔斯回答中的编辑是关于 Scala 2.8 的,它在 2.9 中再次发生了变化......我知道这很令人困惑。
【解决方案4】:

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

【讨论】:

  • 感谢 Vitalii,我看了 asScalaMap 并且还有 asScalaMap 的版本,它允许从 java Properties 实例到 Scala 可变 Map[String, String] 的隐式转换。
【解决方案5】:

在 Scala 2.13.2 中:

import scala.jdk.javaapi.CollectionConverters._

val props = asScala(System.getProperties)

【讨论】:

    【解决方案6】:

    看起来在最新版本的 Scala(截至本答案时为 2.10.2)中,首选方法是使用来自 scala.collection.JavaConverters 的显式 .asScala

    import scala.collection.JavaConverters._
    
    val props = System.getProperties().asScala
    
    assert(props.isInstanceOf[Map[String, String]])
    

    【讨论】:

    • 这是 IMO 的最佳答案。谢谢。
    猜你喜欢
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    相关资源
    最近更新 更多