Java-15.7 Map (4)-Introduction to the working principle of HashMap-hash collision (often used as an interview)
In this section, we will discuss hash collision.
1. What is hash collision?
That is, the hashcode of the key of the two objects is the same. How can we get its value at this time?
The answer is to traverse the Entry linked list at the position of the table through equals.
2. Example
Normal example:
package com.ray.ch14;import java.util.HashMap;public class Test {public static void main(String[] args) {HashMap
map = new HashMap
();Person person_1 = new Person();person_1.setHeight(180);person_1.setId(1);person_1.setName("person_1");Person person_2 = new Person();person_2.setHeight(180);person_2.setId(2);person_2.setName("person_1");Dog dog_1 = new Dog();dog_1.setId(1);dog_1.setName("dog_1");Dog dog_2 = new Dog();dog_2.setId(2);dog_2.setName("dog_2");map.put(person_1, dog_1);map.put(person_2, dog_2);System.out.println("--" + map.get(person_1).getName());System.out.println("--" + map.get(person_2).getName());}}class Dog {private int id = 0;private String name = "";public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic int hashCode() {System.out.println("dog's hashCode() invoked");return id;}@Overridepublic boolean equals(Object obj) {System.out.println("dog's equals invokes");return super.equals(obj);}}class Person {private int id = 0;private String name = "";private int height = 0;@Overridepublic int hashCode() {System.out.println("person id:" + id + ",hashCode() invoked,"+ "hashcode:" + this.name.hashCode() + this.height);return super.hashCode();}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}@Overridepublic String toString() {return "id:" + id + "; Name:" + this.name + "; height:" + this.height;}@Overridepublic boolean equals(Object obj) {System.out.println("id:" + id + ", equals invokes");return super.equals(obj);}}
Output:
Person id: 1, hashCode () invoked, hashcode: 443164103180
Person id: 2, hashCode () invoked, hashcode: 443164103180
Person id: 1, hashCode () invoked, hashcode: 443164103180
-- Dog_1
Person id: 2, hashCode () invoked, hashcode: 443164103180
-- Dog_2
Explanation:
(1) create two classes above and add the output statements in the hashCode and equal methods respectively.
(2) the output shows that the rewritten equals method is not called. We only need to use hashcode to locate the corresponding object.
Hash collision code:
Package com. ray. ch14; import java. util. HashMap; public class Test {public static void main (String [] args) {HashMap
Map = new HashMap
(); Person person_1 = new Person (); person_1.setHeight (180); person_1.setId (1); person_1.setName ("person_1"); Person person_2 = new Person (); person_2.setHeight (180); person_2.setId (2); person_2.setName ("person_1"); Dog dog_1 = new Dog (); dog_1.setId (1); dog_1.setName ("dog_1 "); dog dog_2 = new Dog (); dog_2.setId (2); dog_2.setName ("dog_2"); map. put (person_1, dog_1); map. put (person_2, dog_2); System. out. println ("--" + map. get (person_1 ). getName (); System. out. println ("--" + map. get (person_2 ). getName () ;}} class Dog {private int id = 0; private String name = ""; public int getId () {return id;} public void setId (int id) {this. id = id;} public String getName () {return name;} public void setName (String name) {this. name = name ;}@ Overridepublic int hashCode () {System. out. println ("dog's hashCode () invoked"); return id ;}@ Overridepublic boolean equals (Object obj) {System. out. println ("dog's equals invokes"); return super. equals (obj) ;}} class Person {private int id = 0; private String name = ""; private int height = 0; @ Overridepublic int hashCode () {System. out. println ("person id:" + id + ", hashCode () invoked," + "hashcode:" + this. name. hashCode () + this. height); return this. name. hashCode () + this. height; // override place} public int getId () {return id;} public void setId (int id) {this. id = id;} public String getName () {return name;} public void setName (String name) {this. name = name;} public int getHeight () {return height;} public void setHeight (int height) {this. height = height ;}@ Overridepublic String toString () {return "id:" + id + "; Name:" + this. name + "; height:" + this. height ;}@ Overridepublic boolean equals (Object obj) {System. out. println ("id:" + id + ", equals invokes"); return super. equals (obj );}}
Output:
person id:1,hashCode() invoked,hashcode:443164103180person id:2,hashCode() invoked,hashcode:443164103180id:2, equals invokesperson id:1,hashCode() invoked,hashcode:443164103180id:1, equals invokes--dog_1person id:2,hashCode() invoked,hashcode:443164103180--dog_2
Explanation:
(1) We have rewritten the Person method, that is, the hashCode method of the key, to generate hash collisions manually.
(2) the output shows that the above Code requires the equals method.
Returns the source code of put and get;
The following is the source code of put:
Public V put (K key, V value) {if (key = null) return putForNullKey (value); int hash = hash (key. hashCode (); int I = indexFor (hash, table. length); for (Entry
E = table [I]; e! = Null; e = e. next) {Object k; if (e. hash = hash & (k = e. key) = key | key. equals (k) {// note that V oldValue = e. value; e. value = value; e. recordAccess (this); return oldValue;} modCount ++; addEntry (hash, key, value, I); return null ;}
The following is the source code of get:
Public V get (Object key) {if (key = null) return getForNullKey (); int hash = hash (key. hashCode (); for (Entry
E = table [indexFor (hash, table. length)]; e! = Null; e = e. next) {Object k; if (e. hash = hash & (k = e. key) = key | key. equals (k) // return e. value;} return null ;}
Note ":
(1) If there is no hash collision, the previous two hash comparisons can be compared with the key address, followed by a "Short Circuit, so that the subsequent sentence is no longer executed.
(2) but in the case of hash collision, the first two conditions are true, and then the last equals must be used to determine the equality of objects.
3. What is the hash collision?
(1) It usually appears in Big Data scenarios.
(2) The hashcode generation method has weak uniqueness (for example, the above human-generated hashcode)
Summary: This chapter mainly introduces the working principle of HashMap by introducing hash collision.
This chapter is here. Thank you.