Can I create a collection in Scala that uses different equals/hashCode/compare implementations?

StackOverflow https://stackoverflow.com/questions/2662020

  •  27-09-2019
  •  | 
  •  

Question

I'm looking for as simple way to create an identity set. I just want to be able to keep track of whether or not I've "seen" a particular object while traversing a graph.

I can't use a regular Set because Set uses "==" (the equals method in Scala) to compare elements. What I want is a Set that uses "eq."

Is there any way to create a Set in Scala that uses some application-specified method for testing equality rather than calling equals on the set elements? I looked for some kind of "wrapEquals" method that I could override but did not find it.

I know that I could use Java's IdentityHashMap, but I'm looking for something more general-purpose.

Another idea I had was to just wrap each set element in another object that implements equals in terms of eq, but it's wasteful to generate tons of new objects just to get a new equals implementation.

Thanks!

Was it helpful?

Solution

This is a similar question. The accepted answer in that case was to use a TreeSet and provide a custom Comparator.

OTHER TIPS

Depending on your needs you could create a box for which you use identity checks on the contained element such as:

class IdentBox[T <: AnyRef](val value: T) {

    override def equals(other: Any): Boolean = other match {
      case that: IdentBox[T] => that.value eq this.value
      case _ => false
    }

    override def hashCode(): Int = value.hashCode

  }

And make the collection to contain those boxes instead of the elements directly: Set[IdentBox[T]]

It has some overhead of boxing / unboxing but it might be tolerable in your use case.

Since you don't require a reference to the "seen" objects, but just a boolean value for "contains", I would suggest just using a mutable.Set[Int] and loading it with values obtained by calling System.identityHashCode(obj).

Scala custom collections have enough conceptual surface area to scare off most people who want a quick tweak like this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top