Hoe stelt scala intersection & match in een set

Ik heb twee sets objets en ik wil de kruising van de twee sets krijgen. De objecten in de sets zien er als volgt uit

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

}

In een andere klas krijg ik de sets gebruikers en wil ik de kruising zien.

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

De bovenstaande code werkt niet en wordt afgedrukt

Set()

Nochtans als ik manueel loop over de reeksen gebruikend foreach krijg ik het gewenste resultaat

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

de bovenstaande code wordt afgedrukt

Set(Matt, Cass, Joe, Erin)

Dit werkt prima

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

println(set1 & set2)

De bovenstaande afdrukken

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 echt?
toegevoegd de auteur agilesteel, de bron

3 antwoord

Van JavaDoc:

Houd er rekening mee dat het over het algemeen noodzakelijk is om de hashCode-methode te negeren   wanneer deze methode wordt opgeheven, om het algemene te behouden   contract voor de hashCode-methode, waarin staat dat gelijke objecten moeten   hebben dezelfde hashcodes.

Van ScalaDoc:

Bovendien is het meestal noodzakelijk om deze methode te overschrijven   hashCode opheffen om ervoor te zorgen dat objecten die "gelijk" zijn   (o1.equals (o2) levert true op) hash op dezelfde Int.   (O1.hashCode.equals (o2.hashCode)).

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

1
toegevoegd

Ik ben hier niet 100% positief over, maar ik denk dat uw probleem wordt veroorzaakt door een aangepaste is gelijk aan zonder een bijbehorende aangepaste hashCode . Ik ben een beetje verrast dat je hash-sets überhaupt werken, eigenlijk ...

Je handmatige lus door de elementen van elke set werkt natuurlijk goed, omdat je helemaal geen hashCode aanroept :)

1
toegevoegd
de hash-code toegevoegd en het werkte dankzij mergeconflict maar niet voordat je een meer scala-versie van het kruispunt uitwerkt die niet aan onveranderlijkheid lijdt als iemand geïnteresseerd is def heeft [A] (set: Set [A], doel: A): Boolean = {set.foldLeft (false) {(rv, item) => rv || target == item}} def union [A] (set1: Set [A], set2: Set [A]): ​​Set [A] = {set1.foldLeft (Set [A] ()) {(vak, item) => {if (has (set2, item)) union + item else union}}}
toegevoegd de auteur Matt Higgins, de bron

Wanneer u is gelijk aan overschrijft, moet u er altijd hashCode mee overnemen.

0
toegevoegd