假设我想Object
通过某种方法在某种高级算法的过程中处理某个类的多个对象treat(Object o)
。在这种算法中,可能会出现相同的对象(没有相同的地址),因此我不想对待这些相同的对象中的每个对象,只出现第一个,而忽略其他对象。
一个简单的解决方案是实现一种ArrayList
结构来存储所有已处理的对象,名为treated
,并执行以下操作。
if (!treated.contains(o)){
treat(o);
treated.add(o);
}
但是,我认为该contains
方法在线性时间内运行,而使用a HashSet
代替an ArrayList
则可以在恒定时间内进行。
但是,这是我的问题:相同的哈希码不能确保相等。换句话说,使用HashSet treated
如下:
if (!treated.contains(o)){
treat(o);
treated.add(o);
}
可能不会对待所有不同的对象,因为某些对象o1
可能最终具有与其他对象相同的哈希码o2
。如果o1
得到治疗,则o2
不会,反之亦然。就一个HashMap treated
,旁边的一些使用equals()
,更适合我的问题?
if (treated.containsKey(o.hashCode())){
Object o2 = treated.get(o.hashCode());
if (!o.equals(o2)){
treat(o);
}
} else {
treat(o);
treated.put(o.hashCode(), o);
}
对于此问题,推荐的方法是什么?
注意:我已经看到有关使用“完美哈希码”的评论,即为每个唯一对象分配唯一值的哈希码,因此无法为不同对象获得类似的哈希码。我不认为这是解决方案,因为(从理论上来说)我可以处理任意数量的不同对象,而哈希码的类型int
有效地限制了不同哈希码的数量。
换句话说,
HashSet treated
如下使用可能不会对待所有不同的对象,因为某些对象o1最终可能具有与不同的对象o2相同的哈希码
这是基于HashSet.contains
仅检查哈希码的错误假设。它不是-它使用哈希码来找到相等的候选者,但是然后equals
像往常一样检查实际的相等性。
如果此集合包含指定的元素,则返回true。更正式地讲,当且仅当此集合包含元素e这样使得返回true
Objects.equals(o, e)
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句