Ordered / Ordering - creating one for library classes which don't have them


#1

Hello,

I’ve asked a question on ordering before but since there are so many possibilities brought up, I’m never sure how to proceed so am keen to know whether there is a clear winner.

I am using someone else’s class system. They have a subclass B of a class A. A implements Comparable.

I think from what I’ve read, since B doesn’t implement Comparable then only aspects of class A in objects of type B can be used when sorting. This wouldn’t be enough so I would like to create my own sorting methods for class B.

Without using extensions, what would be the most natural way to proceed? I understand there is a problem with Ordered / Ordering because of a bug that one of the classes has the wrong variance annotation.

Would implicits conversions be best to a class of my own and then making it implement say Ordered?

If so, which sort method would then be used to sort a list or array of objects of them?

Thanks,


#2

Sounds to me you want to provide your own Ordering[A], for example something like:

object ABOrdering extends Ordering[A] {

def compare(a1: A, a2: A): Int = {

(a1, a2) match {

case (b1: B, b2: B) => ???

case (b1: B, _) => ???
case (_, b2: B) => ???

case (_, _) => a1.compareTo(a2)

}
}

}


#3

Thanks,
I’m experimenting with the existing objects extending comparable for now.

Would you know why this doesn’t work? (the variables have to be converted for Array[Object] it seems for it to work)

val vars: Array[Object] = Array(bp, dp, sp)
println(vars.toList)
println(java.util.Arrays.sort(vars))

Gives:

[info] List(bp, dp, sp)
[info] ()

vars is a val so can’t be mutated but there is no error message?


#4

vars is a val (final pointer) which means it cannot be updated to point to some other value after being assigned, but the value it points to is an Array, which is a mutable datastructure.


#5

A val can’t be re-assigned, but the declaration doesn’t know or have anything to say about the mutability of the assigned value.

i.e. if we have a mutable class

class Box {
  private var _i = 0
  def i = _i
  def set(ii: Int): Unit = _i = ii
}

then

val b = new Box //sure
println(b.i) //prints 0
b.set(7) //sure
println(b.i) //prints 7
b = new Box //won't compile, re-assignment to val