Matt Higgins
Matt Higgins

Reputation: 183

How does scala intersection & match elements in a set

I have two sets of objets and I want to get the intersection of the two sets. The objects in the sets look like this

@BeanInfo
class User {

  @JsonProperty
  @BeanProperty
  var name:String = ""

  @JsonProperty
  @BeanProperty
  var id:Long = 0

  override def toString = name

  override def equals(other: Any)= other match {
      case other:User => other.id == this.id
      case _ => false
   }

}

In another class I get the sets of users and want to see the intersection.

val myFriends = friendService.getFriends("me")
val friendsFriends = friendService.getFriends("otheruser")
println(myFriends & friendsFriends) 

The above code does not work and prints

Set()

However if I manually loop over the sets using foreach I get the desired result

var matchedFriends:scala.collection.mutable.Set[User] = new HashSet[User]()    
myFriends.foreach(myFriend => {
  friendsFriends.foreach(myFriend => {
      if(myFriend == myFriend){
        matchedFriends.add(myFriend)
      }
  })
})
println(matchedFriends)

the above code prints

Set(Matt, Cass, Joe, Erin)

This works just fine

val set1 = Set(1, 2, 3, 4)
val set2 = Set(4,5,6,7,1)

println(set1 & set2)

The above prints

Set(1, 4)

Do the set operations & &- etc.. only work on primitive objects ? Do I have to do something additional to my user object for this to work ?

Upvotes: 0

Views: 2326

Answers (3)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297305

From JavaDoc:

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

From ScalaDoc:

Additionally, when overriding this method it is usually necessary to override hashCode to ensure that objects which are "equal" (o1.equals(o2) returns true) hash to the same Int. (o1.hashCode.equals(o2.hashCode)).

Set is not working because you broke hashCode when you overrode equals.

Upvotes: 1

mergeconflict
mergeconflict

Reputation: 8276

I'm not 100% positive about this, but I think your issue is caused by having implemented a custom equals without a corresponding custom hashCode. I'm sort of surprised your hash sets are working at all, actually...

Your manual loop through the elements of each set works fine, of course, because you don't call hashCode at all :)

Upvotes: 1

agilesteel
agilesteel

Reputation: 16859

When overriding equals always override hashCode with it.

Upvotes: 0

Related Questions