2010-01-06 2 views
12

Я пытался перетащить переменные среды в скрипт scala с использованием java-итераторов и/или перечислений и понял, что д-р Франкенштейн может требовать отцовства, поэтому вместо этого я взломал следующее из уродливого дерева:Получение карты Scala из свойств Java

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

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

+1

Scala gem, а? Rubyist? –

+0

Нет, Руби слишком классный для меня, догадываюсь, что это была копия Стэна Липпмана на C++ Gems на полке, которая попалась мне на глаза. –

ответ

7

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, но там вы идете. Имея в виду, это делает неявный вариант гораздо менее привлекательным. В этом случае альтернатива является наиболее кратким из них.

EDIT

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

+0

В качестве примечания, это первый раз, когда я делаю Java <-> Преобразование коллекции Scala. В последний раз, когда я пытался, я не был достаточно опытным, чтобы заставить его работать. И у меня не только был шанс преодолеть мое предыдущее поражение, но я нахожу эту конкретную проблему, представляющую большой интерес, так как я сейчас и сейчас просматриваю свойства системы! –

+0

Спасибо, Дэниэл, я дам ваш ответ надлежащим образом. Я рад, что вызвал ваш интерес к этой теме. –

+0

@ Даниэль, я подозреваю, что это жемчужина, которую я искал, просто позор за актерским составом, тем более что Properties должен реализовать Map [String, String]. Эти преобразования - отличная находка для меня. –

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)) 
} 
+0

Спасибо Виталию, я посмотрел на asScalaMap, а также есть версия asScalaMap, которая позволяет неявное преобразование из экземпляра java Properties в изменяемую Scala Map [String, String]. –

7

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

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 на него.

+0

Благодарим за обновление. Даниэль предоставил для редактирования ответ, в котором упоминаются эти импликации. По иронии судьбы доступ к среде будет еще более простым в scala 2.10, просто используйте неизменяемую карту, возвращаемую методом sys.env. –

+2

Просто понял, что это было преобразование свойств в карту Scala, о которой я просил, однако Scala 2.10 также имеет метод sys.props для доступа к свойствам системы. –

+1

Редактирование в ответ Дэниелса о Scala 2.8, и оно снова изменилось в 2.9 ... Я знаю, что это сбивает с толку. – iwein

1

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

import scala.collection.JavaConverters._ 

val props = System.getProperties().asScala 

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

Это лучший ответ ИМО. Благодарю. – Jabba

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) 
+0

Привет, Сарат. Благодарим за участие в сайте. Мы предпочитаем ответы на StackOverflow, чтобы получить немного больше объяснений, чем просто код публикации. Попробуйте прочитать это [руководство по публикации хороших ответов] (http://stackoverflow.com/help/how-to-answer) для получения дополнительной справки :) – starsplusplus

 Смежные вопросы

  • Нет связанных вопросов^_^