萍聚社区-德国热线-德国实用信息网

 找回密码
 注册

微信登录

微信扫一扫,快速登录

萍聚头条

查看: 1023|回复: 7

[职业生涯] 一个问题,java高手进

[复制链接]
发表于 2016-8-10 20:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册 微信登录

x
本帖最后由 傻卵 于 2016-8-10 21:30 编辑

工作中遇到一个非常奇怪的问题,求java高手牛人解答:

很简单的一个问题,竟然找不到答案,欲哭无泪啊:

现在有一个 Set<Taetigkeit> taetigkeiten  (HashSet)

taetigkeiten 里有一个 objekt  ----- taetigkeit

现在用 taetigkeiten.remove(taetigkeit)  方法,想删除这个Objekt, 结果怎么删也删不掉!!!

检查了一下:

taetigkeiten.size() == 1  -------> 结果为 true

taetigkeiten.iterator().next() == taetigkeit  -----> 结果为 true

taetigkeiten.iterator().next().equals(taetigkeit) ------> 结果为true

taetigkeiten.iterator().next().getHashCode().equals(taetigkeit.getHashCode()) -----> 结果为true

上面这些测试可以证明两个objekt是同一个objekt,结果不能删除!

第一次遇到这个问题,以前从来没发生过,真的非常奇怪,这种最简单的竟然出问题! 来论坛请教下高人吧,谁知道是怎么回事?



Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
发表于 2016-8-10 21:35 | 显示全部楼层
把你重写的taetigkeit里面的hashcode和equals方法发来看看.
还可以在remove设断点调试,记录你调用remove的时候那个taetigkeit的hash码和当时set里面的那个taetigkeit的hash码.
或者简单试试再add一个taetigkeit看set会不会拒绝.
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
 楼主| 发表于 2016-8-10 22:13 | 显示全部楼层
本帖最后由 傻卵 于 2016-8-10 22:16 编辑
gaokx 发表于 2016-8-10 21:35
把你重写的taetigkeit里面的hashcode和equals方法发来看看.
还可以在remove设断点调试,记录你调用remove的 ...

taetigkeit 里面没写hashcode和equals方法,而是直接用某个开源库提供的一个 hashcode 注解,我想不起具体是哪个了

我没断点看当时的hashcode是否一致,但用system.out. 或者 logger上打印出来的两个hashcode是一样的

我也没试set能否再add新taetigkeit,但从程序来看,这个taetigkeit就是新加进去的,因为set一开始是空的

后来我用最笨的办法绕过了这个问题

Set<Taetigkeit> aktuelleTaetigkeiten = new HashSet<>()

for (Taetigkeit t : taetigkeiten) {
    if (!t.equals(taetigkeit)) {
        aktuelleTaetigkeiten.add(t)
    }
}

然后直接用aktuelleTaetigkeiten就行了, 我把代码这样提交了(很不负责任的),反正也没人看见,不过这个问题很奇怪,还是要搞清楚什么原因

Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
发表于 2016-8-10 22:40 | 显示全部楼层
解决了就好,基本上看你描述问题就出在对对象是否相等的判断上,如果hashset用你想移除的那个obj和他里面包含的obj比较得出结果是不一致,就不会移除.一般这种情况就是去检查hashcode和equals方法的实现,

hashset判断是否重复的工作原理搜一下就有,首先调用 obj 的 hasCode 方法得到该对象的哈希码,HashSet 会把它的哈希码转换成一个数组下标来记录这个obj 的位置.位置是空,那么就把obj对象添加到链表上,如果不为空,那就遍历这个链表,用obj的equals方法来判断是否和其中的某个元素重复.

如果出现你创建两个同样的对象但是都可以放入hashset的情况,那基本上就是hashcode和equals实现有问题
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
 楼主| 发表于 2016-8-10 22:54 | 显示全部楼层
gaokx 发表于 2016-8-10 22:40
解决了就好,基本上看你描述问题就出在对对象是否相等的判断上,如果hashset用你想移除的那个obj和他里面包含 ...

明白了,谢谢

等我明天按这个思路去试试!

你说的没错,应该是hashCode的问题,我记得 taetigkeiten.contrains(taetigkeit) 为 false, 很奇怪,所以可能是这个hashcode注解有问题,没起作用,或者出错了
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
发表于 2016-8-11 11:58 | 显示全部楼层
如你所描述,这个Hashset是Immutable的,来自某个(接口),不允许编辑
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
发表于 2016-8-11 21:22 | 显示全部楼层
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
 楼主| 发表于 2016-8-11 22:53 | 显示全部楼层
原因已经找到了,就是开源第三方hashcode注解配置错误,这个不是我做的,是我们专门负责系统配置的做的
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
您需要登录后才可以回帖 登录 | 注册 微信登录

本版积分规则

手机版|Archiver|AGB|Impressum|Datenschutzerklärung|萍聚社区-德国热线-德国实用信息网

GMT+2, 2024-11-2 15:42 , Processed in 0.086122 second(s), 16 queries , MemCached On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表