TreeMap
?
Ну, это озадачило меня на некоторое время. Ответ лежит в мире импликатов и преобразователей типов приемников.
В скорлупе орехов scala.collection.immutable.TreeMap
является SortedMap
. Если вы посмотрите на документацию по TreeMap
, вы увидите, что в качестве неявного аргумента принимается Ordering[T]
.
Обычно, когда вы объявляете TreeMap
, скажем, встроенный, он будет использовать объект Ordering
по умолчанию, например, так:
1
2
|
scala> val dtm = TreeMap( "a" -> 1 , "bc" -> 2 , "def" -> 3 ) dtm : scala.collection.immutable.TreeMap 1 = Map(a -> 1 , bc -> 2 , def -> 3 ) |
Если вы хотите изменить порядок ключей, например, вместо возрастающего порядка по содержимому String, скажем, в порядке убывания длины строк, вам нужен тип Ordering.
1
2
3
4
|
scala> object VarNameOrdering extends Ordering[String] { def compare(a : String, b : String) = b.length compare a.length } defined module VarNameOrdering |
Теперь вы можете использовать второй список аргументов в явном виде, например так:
1
2
|
scala> val tm 1 = TreeMap( "a" -> 1 , "bc" -> 2 , "def" -> 3 )( VarNameOrdering ) tm : scala.collection.immutable.TreeMap 1 = Map( def -> 3 , bc -> 2 , a -> 1 ) |
Мы передаем объект в TreeMap
, который довольно похож на объект Java Collection Comparator
без создания шаблона. Ключи TreeMap теперь упорядочены по длинам строк. Мы добавим больше элементов, и карта останется упорядоченной.
1
2
|
val tm 2 = tm 1 + ( "food" -> 4 ) cala.collection.immutable.TreeMap 1 = Map(food -> 4 , def -> 3 , bc -> 2 , a -> 1 ) |
Однако, предостережение, нужно быть осторожным и помнить, что карты обычно реализуются в виде хэшей.
1
2
|
scala> val tm 3 = tm 2 + ( "z" -> 5 ) tm 3 : scala.collection.immutable.TreeMap 1 = Map(food -> 4 , def -> 3 , bc -> 2 , z -> 5 ) |
Удивлены? Вы должны быть.
Другой способ сортировки карты — просто получить доступ к ключам и выполнить сортировку.
1
2
3
4
5
6
7
8
|
scala> dtm.keys.toList.sortWith ( _ .length > _ .length ) res 3 : List 1 = List(salad, def , bc, a) scala> dtm.keys.toList.sortWith ( _ .length > _ .length ).map( k = > ( dtm.get(k).get )) res 4 : List[Int] = List( 10 , 3 , 2 , 1 ) scala> dtm.keys.toList.sortWith ( _ .length > _ .length ).map( k = > ( k, dtm.get(k).get )) res 5 : List[(java.lang.String, Int)] = List((salad, 10 ), ( def , 3 ), (bc, 2 ), (a, 1 )) |
Это может быть лучшим решением, так как вы не потеряли ключ в полете! Рассмотрение того, как будут храниться данные, является важным решением, которое необходимо принять на ранней стадии. Вы всегда можете решить, как написать проекцию этих данных намного позже.
Наконец, интересно увидеть параллели между Java и Scala
1
2
3
4
5
|
scala> dtm.keys res 6 : Iterable 1 = Set(a, bc, def , salad) scala> dtm.keys.toList res 7 : List 1 = List(a, bc, def , salad) |
Ссылка: Индивидуальный заказ Scala TreeMap от нашего партнера JCG Питера Пилигрима в блоге Питера Пилигрима .