Як елементи scala перетинаються та збігаються в наборі

У мене є два набори об'єктів, і я хочу отримати перетину цих двох наборів. Об'єкти в наборах виглядають так

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

0
myFriend == myFriend дійсно?
додано Автор agilesteel, джерело

3 Відповіді

З JavaDoc:

Зауважте, що зазвичай потрібно переопределити метод hashCode   кожного разу, коли цей метод перекритий, щоб підтримувати загальне   договір для методу hashCode, який говорить, що рівні об'єкти повинні   мають рівні хеш-коди.

З ScalaDoc:

Крім того, при переході на цей метод, як правило, необхідно   замінити hashCode, щоб переконатися, що об'єкти, які є "рівними"   (o1.equals (o2) повертає true) хеш до того самого Int.   (o1.hashCode.equals (o2.hashCode)).

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

1
додано

Я не на це 100% позитивно, але я думаю, що ваша проблема виникла через застосування користувацького equal без відповідного спеціального hashCode . Мені зовсім не дивно, що ваші набори хеш працюють взагалі, насправді ...

Ваш ручний цикл через елементи кожного набору відмінно працює, звичайно, тому що ви не називаєте hashCode взагалі :)

1
додано
додано хеш-код, і він працював спасибі mergeconflict, але не перед тим, як опрацювати більш версію scala перехрестя, яка не зазнає незмінності, якщо хтось зацікавлений def має [A] (set: Set [A], target: A): Boolean = {set.foldLeft (false) {(rv, item) => rv || target == item}} def union [A] (set1: Set [A], set2: Set [A]): ​​Встановити [A] = {set1.foldLeft [Set [A] ()) {(union, item) => {if (має (set2, item)) union + item else union}}}
додано Автор Matt Higgins, джерело

При перевизначенні equal завжди збігаються з hashCode .

0
додано
ІТ КПІ - Scala
ІТ КПІ - Scala
45 учасників