Как скала пересечения и сопоставления элементов в наборе
У меня есть два набора объектов, и я хочу, чтобы пересечение этих двух наборов. Объекты в наборах выглядят так
@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
с этим.