Java uses a custom class as the HashMap key value instance _java

Source: Internet
Author: User
Tags null null

This is a classic problem in Java and is often asked in interviews. In fact, a lot of books or articles have mentioned to Overload hashcode () and Equals () two methods to implement a custom key in the HashMap search, but why and if not to do this will have the consequences, as if very little an article, so write an article to explain.

First of all, if we directly use the following person class as a key to deposit in the HashMap, what will happen?

public class Person {

  private String ID;

  Public person (String ID) {
    this.id = ID;
  }
}
Import Java.util.HashMap;

public class Main {public
  static void Main (string[] args) {

    Hashmap<person, string> map = new Hashmap<pe Rson, string> ();

    Map.put (New Person ("001"), "Findingsea");
    Map.put (New Person ("002"), "Linyin");
    Map.put (New Person ("003"), "Henrylin");
    Map.put (New Person ("003"), "Findingsealy");

    System.out.println (Map.tostring ());

    System.out.println (Map.get) (New Person ("001"));
    System.out.println (Map.get) (New Person ("002"));
    System.out.println (Map.get) (New person ("003"));
  }

So what are the output results?

{Person@6e4d4d5e=henrylin, Person@275cea3=findingsea, Person@15128ee5=findingsealy, Person@4513098=linyin}
NULL NULL NULL

We can see that there are two problems here:

1. In the process of adding, we added the key value pairs of key=new person ("003") two times, so in expectation, there should be only one pair of such key pairs in HashMap, because the key (expected) is the same, so it should not be repeated, the second added value= " Findingsealy "should replace the original value=" Henrylin ". But in the input, we found that the expected situation did not appear, but in the HashMap at the same time the value= "Findingsealy" and value= "Henrylin" two key pairs, and their key value is still not the same, which is obviously wrong.

2. When we get the value, we use three person objects to look up, and the three objects are the same as the three key values we just deposited (in our expectation), but it is obviously wrong to find out three null values.

In fact, the correct method is described in many places, directly to the person class to modify, overload the Equals and Hashcode methods, after the modified person class is as follows:

public class Person {

  private String ID;

  Public person (String ID) {
    this.id = ID;
  }

  @Override public
  Boolean equals (Object o) {
    if (this = O) return true;
    if (o = = NULL | | getclass ()!= O.getclass ()) return false;

    person who = (person) o;

    if (ID!= null!id.equals (person.id): person.id!= null) return false;

    return true;
  }

  @Override public
  int hashcode () {return
    ID!= null id.hashcode (): 0;
  }
}

Then, when we re executing the above inspection procedure, we get the following results:

{Person@ba31=findingsea, Person@ba32=linyin, person@ba33=findingsealy}
Findingsea
Linyin
findingsealy

You can see that the bright spot errors that you pointed out are corrected. So why is that?

In HashMap, the comparison order for key lookup is:

1. Compute the hash Code of the object to see if it exists in the table.

2. Check that the object in the corresponding hash code position is equal to the current object.

Obviously, the first step is to use the Hashcode () method, and the second step is to use the Equals () method. When overloading is not done, the two methods of the object class are invoked by default in these two steps, whereas in object the hash code is computed based on the address of the object, and the two person ("003") has a different object address, so their hash Code is also different, natural hashmap will not regard them as the same key. Also, in the object's default Equals (), which is also compared according to the address of the objects, natural one person ("003") and another person ("003") are not equal.

With this in mind, it's easy to figure out why you need to overload both hashcode () and equals two methods at the same time.

• overloaded Hashcode () is for the same key, can get the same hash Code, so that HashMap can be positioned on our designated key.

• overloaded Equals () is to indicate to HashMap that the current object and the object saved on the key are equal, so that we really get the key value pair corresponding to the key.

In another detail, the method of Hashcode () in the person class is:

@Override public
int hashcode () {return
  ID!= null id.hashcode (): 0;
}

There may be some confusion here: why is it possible to use the hash code of a string variable as the hash code value of the person class? Does the hash code for new person (new string ("003")) and new person (new string ("003")) be equal?

Take a look at the output of the following code:

System.out.println ("Findingsea". Hashcode ());
System.out.println ("Findingsea". Hashcode ());
System.out.println (New String ("Findingsea"). Hashcode ());
System.out.println (New String ("Findingsea"). Hashcode ());
728795174
728795174
728795174
728795174

You can see that the output of four statements is equal, and it is intuitive to assume that the string type also overloads Hashcode () to return the hash code value based on the contents of the string, so that the same contents have the same hash code.

At the same time, this illustrates a problem: why is it necessary to compare equals () when the Hashcode () is known to be equal? This is because avoiding the occurrence of the example above, because the person class directly uses the hash code value of the string member of ID as its hash code value based on the overload implementation of the Hashcode () method of the person class, but obviously, A person ("003") and a string ("003") are not equal, so in the case of hashcode () equality, you also need to compare equals ().

The following examples can be used in support of the above statement:

System.out.println (New Person ("003"). Hashcode ()); 47667
System.out.println (New String ("003"). Hashcode ());//47667

System.out.println (New Person ("003"). Equals (New String ("003")); False

Above this Java with a custom class as HashMap key value example is a small series to share all the content of everyone, hope to give you a reference, but also hope that we support cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.