Как скала пересечения и сопоставления элементов в наборе - PullRequest
0 голосов
/ 28 октября 2011

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

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

1 голос
/ 28 октября 2011

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

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

1 голос
/ 28 октября 2011

Из JavaDoc:

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

От ScalaDoc:

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

Set не работает, потому что вы сломали hashCode при превышении equals.

0 голосов
/ 28 октября 2011

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

...