How to use Scala's Ordering#reverse with a TreeMap?
Scala's Ordering
trait has a method reverse
which seems to be the "official" way to get a TreeMap
which is sorted "the wrong" way.
The snippet of the trait looks like this:
trait Ordering[T] extends开发者_开发百科 Comparator[T] with PartialOrdering[T] with Serializable {
outer =>
override def reverse: Ordering[T] = new Ordering[T]{
override def reverse = outer
def compare(x: T, y: T) = outer.compare(y, x)
}
/*snip*/
}
I thought it would work comparable to Java's Collections.reverseOrder
, but Ordering.reverse
doesn't work of course.
How can I use the reverse Ordering with a TreeMap, e. g.:
new TreeMap[Foo, Bar](/*???*/)
new TreeMap[Foo, Bar]()(implicitly[Ordering[Foo]].reverse)
Assuming, of course, that Ordering[Foo]
is implicitly available (such as Ordering[Int]
or Ordering[String]
). If you have it defined as object X
, just pass X.reverse
instead.
Note that the first set of parenthesis here must be empty -- it is only the second set of parenthesis that receive the implicit parameter in this particular case.
new TreeMap[Foo,Bar]()(Ordering[Foo].reverse)
also works. Nice! Succinct and without implicitly
magic.
What's really going on here, if I'm not mistaken:
Odering[Foo]
callsOrdering.apply
, which has an implicit parameter (which is itself of type Ordering)- the implicit def
Ordering.ordered
is found (I'm not sure why) for that parameter and creates a newOrdering
object - that
Ordering
object is passed to and returned byOrdering.apply
reverse
is called on thatOrdering
object and creates another newOrdering
object
I'm mixing run-time and compile-time lingo here, but you'll catch my drift.
new TreeMap[Foo,Bar]()(Ordering.ordered[Foo].reverse)
should work if there is no object for Ordering[Foo]
, as long as Foo extends Ordered[Foo]
(or more generally Foo extends Comparable[Foo]
).
精彩评论