List.retainAll()是否在内部使用HashMap?

时间:2012-04-02 12:42:46

标签: java map hashmap override

我故意违反了hashCode合同,该合同规定如果我们在我们的类中覆盖equals(),我们必须覆盖hashCode(),并且我确保没有与Hash相关的数据结构(如< strong> HashMap , HashSet 等)正在使用它。问题是我担心列表的removeAll()containsAll()等方法可能会在内部使用HashMaps,在这种情况下,由于我没有在我的类中覆盖hashCode(),因此它们的功能可能会中断。

有人可以说明我的疑问是否有效吗?这些类包含许多用于相等比较的字段,我将不得不提出一种有效的技术来使用所有这些字段来获取hashCode。我真的不需要在任何与哈希相关的操作中,因此,我试图避免实现hashCode()

3 个答案:

答案 0 :(得分:3)

来自AbstractCollection.retainAll()

 * <p>This implementation iterates over this collection, checking each
 * element returned by the iterator in turn to see if it's contained
 * in the specified collection.  If it's not so contained, it's removed
 * from this collection with the iterator's <tt>remove</tt> method.

public boolean retainAll(Collection<?> c) {
boolean modified = false;
Iterator<E> e = iterator();
while (e.hasNext()) {
    if (!c.contains(e.next())) {
    e.remove();
    modified = true;
    }
}
return modified;
}

答案 1 :(得分:2)

至于

  

我将不得不提出一种有效的技术来使用所有这些来获取hashCode

您无需在equals实施中使用hashCode使用的所有字段:

  

根据equals方法,如果两个对象不相等则要求,则在两个对象中的每一个上调用hashCode方法必须生成不同的整数结果。但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。

因此,您的hashCode实现可能非常简单并仍然遵守合同:

public int hashCode() {
  return 1;
}

这将确保基于哈希的数据结构仍然有效(性能下降)。如果您将记录添加到您的hashCode实现,那么您甚至可以检查它是否被调用。

答案 2 :(得分:1)

我认为测试hashCode()是否在任何地方被使用的一种简单方法是覆盖你的类的hashCode(),让它打印一个语句到控制台(或者你喜欢的文件),然后返回一些随机值(无所谓,因为你说你不想使用任何基于散列的类)。

但是,我认为最好只是覆盖它,我相信一些IDE甚至可以为你做(例如,Eclipse可以)。如果你从不期望它被召唤,它就不会受到伤害。