รับแผนที่ Scala จากคุณสมบัติ Java

ฉันพยายามดึงตัวแปรสภาพแวดล้อมลงในสคริปต์สกาล่าโดยใช้ java Iterators และ/หรือการแจงนับ และตระหนักว่า 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 นี้ เพียงแสดงสกาล่าเจมที่ฉันเชื่อว่ามีอยู่ในสถานการณ์นี้ (เช่น คุณสมบัติ java --> scala.Map) ขอบคุณล่วงหน้า ;@)


person Don Mackenzie    schedule 06.01.2010    source แหล่งที่มา
comment
ไม่ Ruby เท่เกินไปสำหรับฉัน เดาว่าคงเป็นสำเนาของ C++ Gems ของ Stan Lippman บนชั้นวางที่สะดุดตาฉัน   -  person Don Mackenzie    schedule 07.01.2010


คำตอบ (6)


สกาล่า 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] ซึ่งทำให้โค้ดส่วนใหญ่นั้นมีข้อสงสัย

person Daniel C. Sobral    schedule 06.01.2010
comment
โปรดทราบว่านี่เป็นครั้งแรกที่ฉันทำการแปลงคอลเลกชั่น Java ‹-› Scala ครั้งสุดท้ายที่ฉันพยายาม ฉันไม่มีประสบการณ์เพียงพอที่จะทำให้มันใช้งานได้ และไม่เพียงแต่ฉันจะได้รับโอกาสในการเอาชนะความพ่ายแพ้ครั้งก่อนเท่านั้น แต่ฉันพบว่าปัญหานี้เป็นที่สนใจอย่างมาก เนื่องจากฉันพบตัวเองเป็นครั้งคราวในการอ่านคุณสมบัติของระบบ! - person Daniel C. Sobral; 07.01.2010
comment
ขอบคุณ Daniel ฉันจะให้คำตอบของคุณในภายหลัง ฉันดีใจที่ได้กระตุ้นความสนใจของคุณในหัวข้อนี้ - person Don Mackenzie; 07.01.2010
comment
@Daniel ฉันสงสัยว่านี่คืออัญมณีที่ฉันกำลังมองหา แค่น่าเสียดายเกี่ยวกับนักแสดง โดยเฉพาะอย่างยิ่งเมื่อ Properties ควรใช้ Map[String, String] Conversion เหล่านี้ถือเป็นการค้นพบที่ยอดเยี่ยมสำหรับฉัน - person Don Mackenzie; 07.01.2010
comment
เพื่อให้ชัดเจนว่านักแสดงคือการนำข้อบกพร่องของ Properties ไปใช้ของ Java ไม่ใช่ของ Scala - person Daniel C. Sobral; 07.01.2010
comment
Daniel จอมเวทย์เอลฟ์จอมโกลาหลเอาชนะสัตว์ร้ายตัวร้ายตัวเก่าที่น่ารังเกียจซึ่งเป็นโครงสร้าง Java Properties ขออภัย ความคิดเห็นแรกของคุณทำให้ฉันนึกถึงเกม RPG... - person Travis Schneeberger; 08.01.2010
comment
ไม่มีปัญหา แต่ฉันเป็นนักสู้คนแคระที่ดีตามกฎหมายมากกว่า แม้ว่าฉันจะดูเหมือนเอลฟ์ก็ตาม :-) - person Daniel C. Sobral; 08.01.2010
comment
คำตอบนี้ล้าสมัย (น่าเสียดายที่มันไปกับ Scala) - person iwein; 19.01.2012

สกาล่า 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
สวัสดีสารัช. ขอขอบคุณที่ร่วมให้ข้อมูลกับเว็บไซต์ เราต้องการคำตอบใน StackOverflow เพื่อให้มีคำอธิบายมากกว่าการโพสต์โค้ด ลองอ่านคำแนะนำในการโพสต์คำตอบที่ดีนี้เพื่อรับความช่วยเหลือเพิ่มเติม :) - person starsplusplus; 25.02.2014

ใน 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

person iwein    schedule 19.01.2012
comment
ขอบคุณสำหรับการอัปเดต Daniel ได้แก้ไขคำตอบของเขาโดยกล่าวถึงนัยเหล่านี้ น่าแปลกที่การเข้าถึงสภาพแวดล้อมนั้นจะตรงไปตรงมามากขึ้นใน scala 2.10 เพียงใช้แผนที่ที่ไม่เปลี่ยนรูปซึ่งส่งคืนโดยวิธี sys.env - person Don Mackenzie; 21.01.2012
comment
เพิ่งรู้ว่าเป็นการแปลงคุณสมบัติเป็น Scala Map ที่ฉันขอ แต่ Scala 2.10 ยังมีวิธี sys.props ในการเข้าถึงคุณสมบัติของระบบเช่นกัน - person Don Mackenzie; 21.01.2012
comment
การแก้ไขในคำตอบของ Daniels นั้นเกี่ยวกับ Scala 2.8 และมีการเปลี่ยนแปลงอีกครั้งใน 2.9 ... ฉันรู้ว่ามันน่าสับสน - person iwein; 28.04.2012

ใน 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))
}
person Vitalii Fedorenko    schedule 02.02.2011
comment
ขอบคุณ Vitalii ฉันได้ดู asScalaMap และยังมี asScalaMap เวอร์ชันที่อนุญาตให้มีการแปลงโดยนัยจากอินสแตนซ์คุณสมบัติ java ไปเป็น Map ที่ไม่แน่นอนของ Scala [String, String] - person Don Mackenzie; 05.02.2011

ในสกาล่า 2.13.2:

import scala.jdk.javaapi.CollectionConverters._

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

ดูเหมือนว่าใน Scala เวอร์ชันล่าสุด (2.10.2 ณ เวลาของคำตอบนี้) วิธีที่ต้องการในการทำเช่นนี้คือการใช้อย่างชัดเจน .asScala จาก scala.collection.JavaConverters:

import scala.collection.JavaConverters._

val props = System.getProperties().asScala

assert(props.isInstanceOf[Map[String, String]])
person Erik Kaplun    schedule 10.09.2013
comment
นี่คือคำตอบที่ดีที่สุด IMO ขอบคุณ. - person Jabba; 24.02.2018