Mendapatkan Peta Scala dari Properti Java

Saya mencoba menarik variabel lingkungan ke dalam skrip scala menggunakan Java Iterators dan/atau Enumerations dan menyadari bahwa Dr Frankenstein mungkin mengklaim sebagai orang tua, jadi saya meretas yang berikut ini dari pohon jelek sebagai gantinya:

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

Misalnya untuk mencetak lingkungan yang sama

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

Tolong, tolong jangan mulai memoles t$#d ini, tunjukkan saja permata scala yang saya yakin ada untuk situasi ini (yaitu Java Properties --> scala.Map), terima kasih sebelumnya ;@)


person Don Mackenzie    schedule 06.01.2010    source sumber
comment
Tidak, Ruby terlalu keren untukku, sepertinya salinan Permata C++ Stan Lippman di rak itulah yang menarik perhatianku.   -  person Don Mackenzie    schedule 07.01.2010


Jawaban (6)


Skala 2.7:

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

Meskipun itu memerlukan beberapa typecasting. Biarkan saya mengerjakannya sedikit lagi.

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

Oke, itu mudah. Biarkan saya mengerjakan 2.8 sekarang...

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

Tentu saja, verbositasnya dapat dikurangi dengan beberapa kali impor. Pertama-tama, perhatikan bahwa Map akan menjadi peta yang bisa berubah di 2.8. Sisi baiknya, jika Anda mengonversi kembali peta, Anda akan mendapatkan objek aslinya.

Sekarang, saya tidak tahu mengapa Properties mengimplementasikan Map<Object, Object>, mengingat javadocs dengan jelas menyatakan bahwa kunci dan nilai adalah String, tapi begitulah. Harus mengetikkan ini membuat opsi implisit menjadi kurang menarik. Oleh karena itu, alternatifnya adalah yang paling ringkas.

EDIT

Scala 2.8 baru saja memperoleh konversi implisit dari Properties ke mutable.Map[String,String], yang membuat sebagian besar kode tersebut diperdebatkan.

person Daniel C. Sobral    schedule 06.01.2010
comment
Sebagai catatan tambahan, ini adalah pertama kalinya saya melakukan konversi koleksi Java ‹-› Scala. Terakhir kali saya mencoba, saya tidak cukup berpengalaman untuk membuatnya berfungsi. Dan saya tidak hanya mendapat kesempatan untuk mengatasi kekalahan saya sebelumnya, tetapi saya juga menemukan masalah khusus ini sangat menarik, karena saya kadang-kadang membaca properti sistem! - person Daniel C. Sobral; 07.01.2010
comment
Terima kasih Daniel, saya akan memberikan jawaban Anda dengan benar nanti. Saya senang telah memancing minat Anda pada topik ini. - person Don Mackenzie; 07.01.2010
comment
@Daniel, saya curiga ini adalah permata yang saya cari, sayang sekali tentang pemerannya, terutama karena Properti harus mengimplementasikan Map[String, String]. Konversi ini merupakan penemuan hebat bagi saya. - person Don Mackenzie; 07.01.2010
comment
Untuk memperjelas, pemerannya adalah implementasi kesalahan Properties di Java, bukan kesalahan Scala. - person Daniel C. Sobral; 07.01.2010
comment
Daniel, Chaotic Good Elf Mage mengalahkan monster tua, degil, dan jahat yang merupakan konstruksi Java Properties. Maaf, tapi komentar pertama Anda mengingatkan saya pada RPG... - person Travis Schneeberger; 08.01.2010
comment
Tidak masalah, tapi aku lebih merupakan petarung kurcaci yang baik, meskipun aku terlihat seperti peri. :-) - person Daniel C. Sobral; 08.01.2010
comment
Jawaban ini sudah ketinggalan zaman (sayangnya seperti halnya Scala) - person iwein; 19.01.2012

Skala 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)
person Sarath    schedule 25.02.2014
comment
Hai Sarath. Terima kasih telah berkontribusi pada situs ini. Kami lebih suka jawaban di StackOverflow memiliki penjelasan lebih dari sekedar kode posting. Coba baca panduan untuk memposting jawaban yang bagus untuk bantuan lebih lanjut :) - person starsplusplus; 25.02.2014

Di Scala 2.9.1 hal ini diselesaikan dengan konversi implisit di dalam collection.JavaConversions._ . Jawaban lain menggunakan fungsi yang tidak digunakan lagi. Detailnya didokumentasikan di sini. Ini adalah cuplikan relevan dari halaman itu:

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} 

Beralih dari peta yang bisa berubah ke peta yang tidak bisa diubah hanya dengan memanggil toMap di dalamnya.

person iwein    schedule 19.01.2012
comment
Terima kasih atas pembaruannya, Daniel memberikan edit pada jawabannya dengan menyebutkan implisit ini. Ironisnya, mengakses lingkungan akan menjadi lebih mudah di scala 2.10, cukup gunakan peta abadi yang dikembalikan oleh metode sys.env. - person Don Mackenzie; 21.01.2012
comment
Baru menyadari bahwa itu adalah konversi properti ke Peta Scala yang saya minta, namun Scala 2.10 juga memiliki metode sys.props untuk mengakses properti sistem. - person Don Mackenzie; 21.01.2012
comment
Pengeditan jawaban Daniels adalah tentang Scala 2.8, dan telah berubah lagi di 2.9... Saya tahu ini membingungkan. - person iwein; 28.04.2012

Di Scala 2.8.1 Anda dapat melakukannya dengan asScalaMap(m : java.util.Map[A, B]) dengan cara yang lebih ringkas:

var props = asScalaMap(System.getProperties())

props.keySet.toList.sortWith(_ < _).foreach { k =>
  println(k + (" " * (30 - k.length)) + " = " + props(k))
}
person Vitalii Fedorenko    schedule 02.02.2011
comment
Terima kasih Vitalii, saya melihat asScalaMap dan ada juga versi asScalaMap yang memungkinkan konversi implisit dari instance Java Properties ke Scala yang dapat diubah Map[String, String]. - person Don Mackenzie; 05.02.2011

Dalam Scala 2.13.2:

import scala.jdk.javaapi.CollectionConverters._

val props = asScala(System.getProperties)
person Ava    schedule 16.06.2020

Sepertinya dalam versi terbaru Scala (2.10.2 pada saat jawaban ini dibuat), cara yang lebih disukai untuk melakukan ini adalah menggunakan .asScala dari scala.collection.JavaConverters secara eksplisit:

import scala.collection.JavaConverters._

val props = System.getProperties().asScala

assert(props.isInstanceOf[Map[String, String]])
person Erik Kaplun    schedule 10.09.2013
comment
Ini adalah jawaban terbaik IMO. Terima kasih. - person Jabba; 24.02.2018