简体   繁体   中英

Two lists of same objects have different hash codes

I have a question regarding the hashCode implementation of an List in java.

For better understanding, I will simply describe my data construct. I read graph information from two different databases and store it in a abstract graph representation. Therefore I have two HashMaps, one for each database. The map contains a String as Key and a GraphLayer object as value: HashMap<String, GraphLayer> . The GraphLayer object has two custom members of type PaperMetaData and ConferenceSerieAndInstance . PaperMetaData consists of some members of primitive String type and an member of HashMap<Author, Set<Affiliation>> . The Author contains just primitive String members, as well as Affiliation. ConferenceSerieAndInstance contains also normal String members and a member of type HashMap<String, ConferenceInstance> , where the class ConferenceInstance just conatins String members. I hope, so far everything is clear.

I read out my information from each database and store it in each HashMap for the database. Afterwards I convert each map in a list. So far so good, but the order of the objects in the list is different (as well as in the Map before I convert the map). The cast from HashMap to ArrayList looks like this.

public List<GraphLayer> searchAuthor() { 
    ...
    return (List<GraphLayer>) new ArrayList<GraphLayer>(graph.values());
}

But both lists contains the same objects. If I call the Method hashCode() of each list, I get different hash codes.

I don't understand why I get different hash codes. According to the java documentation, the hash code of a list will be created like that.

  int hashCode = 1;
  for (E e : list)
      hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

So the order of the items in the list should not play a role. If I try it with a list with primitive datatypes, like String, it will work, but not with my custom datatype.

Does anyone has an idea why it does not work?

I compared also each hash code of the members of the PaperMetaData and ConferenceSerieAndInstance in list one, with the hash code of the members in list two. And there is no difference. But if I compare the hashcode of the complete list, there is a difference. I have no idea why. I'm helpless.

Perhaps somebody can help me out. Best regards and thanks in advance.

Your answer lays here

So far so good, but the order of the objects in the list is different (as well as in the Map before I convert the map).

List#equals()

[...] two lists are defined to be equal if they contain the same elements in the same order


EDIT By @SamiKuhmonen

And to elaborate: the hashcode calculation has a loop with summing and multiplying. If hashcodes are 1 and 2 and on another list 2 and 1, the results are 1*31+2 and 2*31+1, so it's clear that they are not the same.


Example

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM