[英]Two lists of same objects have different hash codes
我有一个关于Java中List的hashCode实现的问题。
为了更好地理解,我将仅描述我的数据构造。 我从两个不同的数据库中读取图形信息,并将其存储在抽象图形表示形式中。 因此,我有两个HashMap,每个数据库一个。 该映射包含一个String
作为键,一个GraphLayer
对象作为值: HashMap<String, GraphLayer>
。 GraphLayer对象具有两个类型为PaperMetaData
和ConferenceSerieAndInstance
自定义成员。 PaperMetaData
由一些基本String
类型的成员和HashMap<Author, Set<Affiliation>>
。 作者仅包含原始String成员以及关联。 ConferenceSerieAndInstance
还包含普通的String成员和HashMap<String, ConferenceInstance>
类型的成员,其中ConferenceConference类仅包含String成员。 我希望到目前为止,一切都还清楚。
我从每个数据库中读取我的信息,并将其存储在该数据库的每个HashMap中。 之后,我将每个地图转换为列表。 到目前为止,一切都很好,但是列表中对象的顺序是不同的(以及在转换地图之前,在地图中)。 从HashMap到ArrayList的转换看起来像这样。
public List<GraphLayer> searchAuthor() {
...
return (List<GraphLayer>) new ArrayList<GraphLayer>(graph.values());
}
但是两个列表都包含相同的对象。 如果我调用每个列表的方法hashCode()
, hashCode()
得到不同的哈希码。
我不明白为什么会得到不同的哈希码。 根据Java文档,将像这样创建列表的哈希码。
int hashCode = 1;
for (E e : list)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
因此,列表中项目的顺序不起作用。 如果我尝试使用具有原始数据类型(如String)的列表进行操作,则它将起作用,但不适用于我的自定义数据类型。
有谁知道为什么它不起作用?
我还比较了列表一中PaperMetaData
和ConferenceSerieAndInstance
成员的每个哈希码,与列表二中的成员的哈希码。 而且没有区别。 但是,如果我比较完整列表的哈希码,会有区别。 我不知道为什么。 我很无奈。
也许有人可以帮助我。 最好的问候和预先的感谢。
你的答案就在这里
到目前为止,一切都很好,但是列表中对象的顺序是不同的(以及在转换地图之前,在地图中)。
List#equals()
[...]如果两个列表包含相同顺序的相同元素,则定义为相等
并且要详细说明:哈希码计算具有一个求和与乘法的循环。 如果哈希码是1和2,并且在另一个列表2和1上,则结果是1 * 31 + 2和2 * 31 + 1,因此很明显它们是不同的。
List<String> one = new ArrayList<String>();
List<String> two = new ArrayList<String>();
List<String> three = new ArrayList<String>();
String[] s = "A B C".split(" ");
for (String a : s){
one.add(a);
two.add(a);
}
for (int i = s.length-1 ; i >= 0 ; i--){
three.add(s[i]);
}
System.out.println(one.hashCode()); // 94369
System.out.println(two.hashCode()); // 94369
System.out.println(three.hashCode()); // 96289
System.out.println(one.equals(two)); // true
System.out.println(two.equals(three)); // false
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.