У меня есть два набора объектов, и я хочу получить пересечение двух множеств. Объекты в наборах выглядят так:
@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)
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 ?
Я не на 100% уверен в этом, но я думаю, что ваша проблема вызвана тем, что внедрил собственный equals
без соответствующего пользовательского hashCode
. Я как бы удивлен, ваши хэш-наборы работают вообще, на самом деле ...
Конечно, ваша ручная петля через элементы каждого набора отлично работает, потому что вы вообще не вызываете hashCode
:)
Из JavaDoc:
Обратите внимание, что обычно необходимо переопределить метод hashCode когда этот метод переопределяется, чтобы поддерживать общий контракт для метода hashCode, который утверждает, что равные объекты должны имеют одинаковые хэш-коды.
От ScalaDoc:
Кроме того, при переопределении этого метода обычно необходимо переопределить hashCode, чтобы гарантировать, что объекты, которые являются "равными" (o1.equals (o2) возвращает true) hash к тому же Int. (O1.hashCode.equals (o2.hashCode)).
Set
is not working because you broke hashCode
when you overrode equals
.
Когда переопределение equals
всегда переопределяет hashCode
с ним.