2014-10-21 3 views
0

Скажем, у меня есть некоторые данные в послед в Scala 2.10.2, например:Scala Collection Конкретная реализация

scala> val data = Seq(1, 2, 3, 4, 5) 
data: Seq[Int] = List(1, 2, 3, 4, 5) 

Теперь я выполнить некоторые операции и преобразовать его в карту

scala> val pairs = data.map(i => i -> i * 2) 
pairs: Seq[(Int, Int)] = List((1,2), (2,4), (3,6), (4,8), (5,10)) 

scala> val pairMap = pairs.toMap 
pairMap: scala.collection.immutable.Map[Int,Int] = Map(5 -> 10, 1 -> 2, 2 -> 4, 3 -> 6, 4 -> 8) 

сейчас скажем, по соображениям производительности, я бы хотел, чтобы pairMap использовал HashMap исполнение Map. Каков наилучший способ достичь этого?

Пути Я рассмотрел:

  1. Кастинг:

    pairMap.asInstanceOf[scala.collection.immutable.HashMap[Int,Int]] 
    

    Это кажется немного ужасным.

  2. вручную преобразования:

    var hm = scala.collection.immutable.HashMap[Int,Int]() 
    pairMap.foreach(p => hm += p) 
    

    Но это не очень функциональны.

  3. Использование строитель

    scala.collection.immutable.HashMap[Int,Int](pairMap.toSeq:_*) 
    

    Это работает, но это не самый читаемый фрагмент кода.

Есть ли лучший способ, который мне не хватает? Если нет, то какой из них лучше всего подходит?

ответ

4

Интересный бит: он уже является неизменным HashMap.

scala> val data = Seq(1, 2, 3, 4, 5) 
data: Seq[Int] = List(1, 2, 3, 4, 5) 

scala> val pairs = data.map(i => i -> i * 2) 
pairs: Seq[(Int, Int)] = List((1,2), (2,4), (3,6), (4,8), (5,10)) 

scala> val pairMap = pairs.toMap 
pairMap: scala.collection.immutable.Map[Int,Int] = 
     Map(5 -> 10, 1 -> 2, 2 -> 4, 3 -> 6, 4 -> 8) 

scala> pairMap.getClass 
res0: Class[_ <: scala.collection.immutable.Map[Int,Int]] = 
     class scala.collection.immutable.HashMap$HashTrieMap 

Примечание: литье в качестве хэш-карты вообще не меняет подстилающую вещь. Если вы хотите, чтобы гарантировать строительство HashMap (или какой-то определенный типа), то я рекомендовал бы это:

scala> import scala.collection.immutable 
import scala.collection.immutable 

scala> val pairMap = immutable.HashMap(pairs: _*) 
pairMap: scala.collection.immutable.HashMap[Int,Int] = 
     Map(5 -> 10, 1 -> 2, 2 -> 4, 3 -> 6, 4 -> 8) 

Если вы ищете улучшение производительности вы должны смотреть в использовании mutable.HashMap или java.util.HashMap. Большинство коллекций scala не реализованы коллекциями java.util.

+0

ОК, спасибо. Требование производительности было примером; в общем, это лучший способ получить более конкретную коллекцию? – paulmdavies

+0

Да, это так. Тем не менее, вы должны всегда передавать наиболее общий интерфейс в своей кодовой базе, чтобы избежать ненужных изменений при выборе другого базового типа. (в Эффективной Скале щебета: http://twitter.github.io/effectivescala/) – Nate

+0

Естественно. Иногда, например, использование 'SortedMap' может быть полезно в данной ситуации, например! – paulmdavies

0

Вы можете комбинировать

  • Явного результат типа
  • map: ключ Карты и значение в кортеж
  • breakOut: «вспыхнуть» последовательность кортежей из map, и создать целевой типа непосредственно

как этот

val s = Seq.range(1, 6) 

val m: scala.collection.immutable.HashMap[Int, Int] = 
    s.map(n => (n, n * n))(scala.collection.breakOut) 

, который создает HashMap на лету без промежуточной карты.

С помощью breakOut и явного результата введите соответствующий конструктор для map выбран, и ваш целевой тип создается непосредственно

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