2011-10-27 103 views
0

我有兩組objets,我想要獲取這兩個集合的交集。在集合中的對象是這樣的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) 

但是如果我手動遍歷集合使用的foreach上面的代碼無法正常工作,並打印

Set() 

我得到期望的結果

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) 

Th在作品就好

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

println(set1 & set2) 

上面打印

Set(1, 4) 

不要設定操作& & - 等等。只有在原始對象的工作? 我需要爲我的用戶對象做些額外的工作才能使用它?

+0

'myFriend == myFriend'真的嗎? – agilesteel

回答

1

我對此並不是100%肯定,但我認爲你的問題是由於沒有相應的定製hashCode而實施了自定義equals。我有點驚訝你的哈希集工作可言,其實......

你通過每個集合的元素手動循環工作得很好,當然,因爲你不叫hashCode在所有:)

+0

增加了哈希代碼,它的工作原理感謝mergeconflict,但是在計算出更多的不存在不變性的交叉點之前,如果任何人感興趣的話def不得不使用def [A](set:Set [A],target:A):布爾= { \t set.foldLeft(false){(rv,item)=> rv ||目標==項目} } def union [A](set1:Set [A],set2:Set [A]):Set [A] = { set1.foldLeft(Set [A]()){(如果(具有(set2,item))union + item else union } } }如果(具有(set2,item))聯合,項目)=> { –

0

當覆蓋equals總是覆蓋hashCode與它。

1

,通過javadoc:

注意,一般需要重寫hashCode方法 每當這個方法被覆蓋,以保持hashCode方法,其中指出相等的對象必須 具有一般 合同相同的哈希碼。

從ScalaDoc:

另外,覆蓋該方法時,通常需要以 重載hashCode,以確保它們是 「相等」 對象(o1.equals(O 2)返回true)的散列到同一個Int。 (o1.hashCode.equals(o2.hashCode))。

Set不工作,因爲你打破hashCode當你推翻equals