scala如何交叉&匹配集合中的元素

时间:2011-10-27 20:14:35

标签: scala scala-collections scala-2.9

我有两组objets,我想得到两组的交集。集合中的对象看起来像这样

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

进行设定操作& & - etc ..只适用于原始对象? 我是否必须对我的用户对象执行其他操作才能使其正常工作?

3 个答案:

答案 0 :(得分:1)

我对此并非100%肯定,但我认为您的问题是由于实施了自定义equals而没有相应的自定义hashCode。我有点惊讶你的哈希集正在工作,实际上......

您手动循环浏览每个元素的元素当然可以正常工作,因为您根本不会调用hashCode:)

答案 1 :(得分:1)

来自JavaDoc:

  

请注意,通常需要覆盖hashCode方法   每当重写此方法时,都要保持一般   hashCode方法的契约,它声明了相等的对象必须   有相同的哈希码。

来自ScalaDoc:

  

此外,当覆盖此方法时,通常需要   覆盖hashCode以确保“相等”的对象   (o1.equals(o2)返回true)哈希到同一个Int。   (o1.hashCode.equals(o2.hashCode))。

Set无法正常工作,因为当您覆盖hashCode时,equals已被中断。

答案 2 :(得分:0)

覆盖equals时,始终覆盖hashCode