2

I am trying to instantiate a TreeSet in scala, passing a specific comparator on tuples like this:

  var heads: java.util.TreeSet[(T, Int)] = new java.util.TreeSet[(T, Int)](new Comparator[(T,Int)] {
    def compare(o1: (T, Int), o2: (T, Int)): Int = Ordering[(T, Int)].compare(o1, o2)
  })

However, an implicit ordering on T cannot be found. Should I specify that T <: Comparable[T] in the type hierarchy or is there a simple wayto achieve tuple comparison?

om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
user221218
  • 143
  • 1
  • 1
  • 6

2 Answers2

1

You could add : Ordering (context bound) to the definition of T.

For method:

def method[T: Ordering] = {
  var heads: ...
}

For class:

class MyClss[T: Ordering] {
  var heads: ...
}

There is implicit object Ordering[T] for each subtype of Comparable. But also there are such objects for many other types. For instance for TupleN.

Community
  • 1
  • 1
senia
  • 37,745
  • 4
  • 88
  • 129
1

Since you are comparing tuples, you also need to specify which element to use for comparisons, e.g. if you want to order by the first element of type T:

object Main extends App {
  import java.util.Comparator
  def heads[T: Ordering] = new java.util.TreeSet[(T, Int)](new Comparator[(T,Int)] {
    def compare(o1: (T, Int), o2: (T, Int)): Int = Ordering.by[(T, Int), T](_._1).compare(o1, o2)
  })
  val test = heads[String]
  test.add(("Foo", 42))
  test.add(("Foo", 42))
  test.add(("Bar", 17))
  println(test)
}

This will output [(Bar,17), (Foo,42)].

ValarDohaeris
  • 6,064
  • 5
  • 31
  • 43
  • Are there some particular reasons to use only 1 element for comparisons? – senia May 14 '13 at 13:28
  • 1
    I wasn't aware that there are [predefined Orderings for Tuples](http://www.scala-lang.org/api/current/index.html#scala.math.Ordering$), but there are, so `Ordering[(T, Int)].compare()` works as well, if you want to sort by _1, _2. – ValarDohaeris May 14 '13 at 16:43