scala 交集 & 是如何实现的?匹配集合中的元素

发布于 2024-12-12 10:31:05 字数 1239 浏览 0 评论 0原文

我有两组对象,我想获得两组对象的交集。集合中的对象如下所示

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

。 &- 等..仅适用于原始对象? 我是否必须对我的用户对象做一些额外的事情才能使其工作?

I have two sets of objets and I want to get the intersection of the two sets. The objects in the sets look like this

@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 another class I get the sets of users and want to see the intersection.

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

The above code does not work and prints

Set()

However if I manually loop over the sets using foreach I get the desired result

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

the above code prints

Set(Matt, Cass, Joe, Erin)

This works just fine

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

println(set1 & set2)

The above prints

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

定格我的天空 2024-12-19 10:31:05

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

当然,你对每个集合的元素的手动循环工作得很好,因为你根本不调用 hashCode : )

I'm not 100% positive about this, but I think your issue is caused by having implemented a custom equals without a corresponding custom hashCode. I'm sort of surprised your hash sets are working at all, actually...

Your manual loop through the elements of each set works fine, of course, because you don't call hashCode at all :)

淡写薰衣草的香 2024-12-19 10:31:05

来自 JavaDoc:

注意,一般需要重写hashCode方法
每当此方法被重写时,以保持一般性
hashCode 方法的契约,它规定相等的对象必须
具有相等的哈希码。

来自 ScalaDoc:

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

Set 不起作用,因为您在覆盖 equals 时破坏了 hashCode

From JavaDoc:

Note that it is generally necessary to override the hashCode method
whenever this method is overridden, so as to maintain the general
contract for the hashCode method, which states that equal objects must
have equal hash codes.

From ScalaDoc:

Additionally, when overriding this method it is usually necessary to
override hashCode to ensure that objects which are "equal"
(o1.equals(o2) returns true) hash to the same Int.
(o1.hashCode.equals(o2.hashCode)).

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

握住我的手 2024-12-19 10:31:05

当重写equals时,总是用它重写hashCode

When overriding equals always override hashCode with it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文