【发布时间】:2011-03-04 12:34:58
【问题描述】:
我有一个包含对象列表的数据结构,如下所示:
class A {
private List<Object> list;
}
假设列表的每个元素都有正确的hashCode(),如何正确定义列表的哈希函数?
【问题讨论】:
我有一个包含对象列表的数据结构,如下所示:
class A {
private List<Object> list;
}
假设列表的每个元素都有正确的hashCode(),如何正确定义列表的哈希函数?
【问题讨论】:
如果实际的List 实现完全符合接口,那么提供的hashCode 实现就足够了:
返回此列表的哈希码值。列表的哈希码定义为以下计算的结果:
hashCode = 1;
Iterator i = list.iterator();
while (i.hasNext()) {
Object obj = i.next();
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
List 接口需要符合要求的实现来根据列表的元素提供equals。因此,他们必须明确指定hashCode 算法
【讨论】:
为什么要为列表定义hashCode,而它是already has it implemented(以及equals)?
(当然,如果它是 java.util.List - 但是如果不是,上面的链接会显示您可以用于您自己的列表类型的确切实现。)
【讨论】:
列表的哈希码由列表的List interface 定义。这可以用作对象哈希码的一部分,尽管在某些情况下您可能不想使用它 - 如果列表的元素具有昂贵的哈希码函数,或者列表可以包含对对象,然后如果使用列表的算法,您将获得堆栈溢出。在这种情况下,只需使用列表的长度或其他哈希值。
【讨论】:
在 Java 库中,List 实现(LinkedList、ArrayList)使用AbstractList 提供的默认hashCode 实现。定义为:
int hashCode = 1;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
return hashCode;
【讨论】:
您不这样做的任何具体原因:
Arrays.hashCode(<cast list to array>);
类似:
Arrays.hashCode((String []) myList.toArray());
【讨论】: