Как скала пересечения и сопоставления элементов в наборе

У меня есть два набора объектов, и я хочу, чтобы пересечение этих двух наборов. Объекты в наборах выглядят так

@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
   }

}

В другом классе я получаю наборы пользователей и хочу видеть пересечение.

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

Приведенный выше код не работает и печатает

Set()

Однако, если я вручную перебираю наборы, используя foreach, я получаю желаемый результат

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

вышеуказанный код печатает

Set(Matt, Cass, Joe, Erin)

Это работает просто отлично

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

println(set1 & set2)

Вышеуказанные принты

Set(1, 4)

Операции над множествами & &- и т.д.. работают только с примитивными объектами? Должен ли я сделать что-то дополнительное к моему объекту пользователя, чтобы это работало?

3 ответа

Решение

Я не на 100% уверен в этом, но я думаю, что ваша проблема вызвана внедрением equals без соответствующего обычая hashCode, Я немного удивлен, что ваши хэш-сеты работают вообще, на самом деле...

Конечно, ваш ручной цикл по элементам каждого набора работает нормально, потому что вы не вызываете hashCode совсем:)

Из JavaDoc:

Обратите внимание, что обычно необходимо переопределять метод hashCode всякий раз, когда этот метод переопределяется, чтобы поддерживать общий контракт для метода hashCode, в котором говорится, что равные объекты должны иметь одинаковые хеш-коды.

Из ScalaDoc:

Кроме того, при переопределении этого метода обычно необходимо переопределить hashCode, чтобы гарантировать, что объекты, которые являются "равными" (o1.equals(o2) возвращает true), хэшируют к тому же Int. (O1.hashCode.equals(o2.hashCode)).

Set не работает, потому что ты сломал hashCode когда ты переиграл equals,

При переопределении equals всегда переопределять hashCode с этим.

Другие вопросы по тегам