class Mappable[T](val instance: T, private val accessor: T => Any) {
override def equals(other: Any): Boolean = other match {
case other : Mappable[T] => accessor(instance) equals accessor(other.instance)
case _ => false
}
override def hashCode(): Int = accessor(instance).hashCode
}
val userLookup = Map[Int, User]() // Int is the userId
val roleLookup = Map[Int, Role]() // Int is the userId
// ... populate the lookups
for ((userId, role) <- roleLookup) {
val user = userLookup(userId)
// ... do something with user and role
}
class User {
var userId = 0
var userName = ""
}
class MappableAccessor[T](val accessor: T => Any) {
def apply(instance: T): Any = accessor(instance)
}
class Mappable[T](val instance: T)(private val accessor: MappableAccessor[T]) {
override def equals(other: Any): Boolean = other match {
case other : Mappable[T] => accessor(instance) equals accessor(other.instance)
case _ => false
}
override def hashCode(): Int = accessor(instance).hashCode
}
object Implicits {
import scala.language.implicitConversions
implicit def wrap[T](instance: T)(implicit accessor: MappableAccessor[T]): Mappable[T] =
new Mappable(instance)(accessor)
implicit def unwrap[T](wrapped: Mappable[T]): T = wrapped.instance
}
object Main extends App {
import Implicits._
implicit val accessor = new MappableAccessor[User](u => u.userName)
val userSet = scala.collection.mutable.Set[Mappable[User]]()
// Implicit conversions from User to Mappable[User]
userSet += new User() { userId = 1; userName = "bob" }
userSet += new User() { userId = 2; userName = "sally" }
userSet += new User() { userId = 3; userName = "george" }
userSet += new User() { userId = 2; userName = "sally" } // add duplicate
Console.out.println(userSet.size) // size is still 3
val head : User = userSet.head // implicit conversion from Mappable[T] to T
Console.out.println(head.userName)
}
I think (and I could be wrong) that the typical practice in Scala is to use a case class as the Map key when you need a full blown object because of its implied immutable. A non-idempotent implementation of IEqualityComparer or the underlying object is a concern in situations like this, and case classes generally quiet those concerns (even if they can't eliminate it entirely).
ARKBAN--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.