HashMap Code Implementation (JDK7 Array + Chain List)

The first thing we need to do is tap code to implement HashMap, so what is HashMap? What is the data structure? What is the underlying principle?

What is i hashMap?

We all know that hashMap, a storage unit that stores data as key s and value s, should also be used in projects. And hashMap is an out-of-order storage structure, so why is it out of order?

ii HashMap data structure (advantages and disadvantages of arrays and chained lists are in the article on the differences between ArrayList and LInkedList)

JDK7: Array + Chain List

JDK8: Array + Chain List + Red-Black Tree

I believe that many people who have seen the interview also know this. The implementation of our code tapping today is based on JDK7. There is also a point after JDK8.

HashMap is a storage tool that specifies a length of 16 (the length of an array in HashMap). The common method we use in HashMap is put   and   get   Method.

iii Bottom Principles

1.put method

Just now we mentioned that HashMap is an out-of-order storage structure with an array length of only 16, so how does HashMap implement the put method? Bullshit doesn't go too far. It works directly:

First the HashMap put method calculates the remainder of the corresponding hash value of 16 (forced into the int type) using the key value you pass in [it may be more complicated to calculate hashMap, but that's the basic principle], which we call index, and then the HashMap put method uses this index value to determine where to store the data in the array labeled index. So where is the list? Because the index we get is divided by the remainder of 16, there must be duplicate index values, and there will be hash conflicts. The way to avoid hash conflicts is to introduce a chain table. When we find that the index values are duplicated, HashMap replaces the existing values in the array with the values that will be stored and points to the existing values. That might be one-sided, so let me show you in the form of a picture: (The number in the picture is just for ease of understanding, not an actual array or list number)

  Assuming this is an array of sixteen lengths, I'm going to store some data first, a pair of Key s and Value s.


The hash value is the hash value that we computed, followed by the key and value, but now if you have another value to store to 3, this creates a hash conflict and you need to introduce a chain table. (Regardless of what next is, it will be next, look down)

Now save another value, if his hash:12587, key:Map     Value: Map interface, what should I do if this value is also calculated to be saved to position 3 in the diagram? (One more b, I don't want to change it. Just look at it like this, without compromising my understanding.)

  Now we see that the next value in 3 is the key value of the second element in the list, so HashMap resolves the hash conflict. This is one of the logic of HashMap's put method. (Red-Black Tree was introduced in JDK8, which automatically converts to Red-Black Tree storage when the chain table data is greater than 8)

2 HashMap get method

After the put method, let's talk about the get method

hashMap's get method logic is also simple, first by calculating the hash value to find the corresponding location of the array, and then to determine if the key value is equal to the value stored in the array, equality returns the value, inequality returns the value, inequality determines whether the key in the next is empty, not empty, and then the key in the next node is equal until equality returns, or returns empty.

HashMap get, put method principle is finished, let's use code to implement it

iiii Code Implementation (JDK7)

First, we create a Map interface that defines get, put, and size methods.

An Entry interface is defined inside to standardize the format of our Map.

package com.guozm.waimai1.hashmap;

//Define a map class
public interface Map<K,V> {

    //Define put method
    V put(K k,V v);

    //Define the gat method
    V get(K k);

    //Define size
    int size();

    interface Entry<K,V>{
        Object getKey();

        Object getValue();

Then define a HashMap, Entry class to implement Map, Entry class methods (including methods to calculate index and find key s recursively) there are comments in the code that can be viewed.

package com.guozm.waimai1.hashmap;

//Map Implementation Class
public class HashMap<K,V> implements Map<K,V> {

    //Create Array Object
    private Entry table[] = null;

    //Initialize size
    int size = 0;

    //Construction method
    public HashMap() {
        //hashMap array capacity is 16
        table = new Entry[16];

     * 1.hash operation with key
     * 2.Get index-->array subscript--->object corresponding to array--->Entry
     * 3.To determine if the current object is empty, empty: you can store the data directly, not empty: hash conflict
     * 4.Chain list is required to resolve hash conflicts
     * 5.Return Stored Results
     * @param k
     * @param v
     * @return
    public V put(K k,V v) {
        //Get hash by calculating
        int index = hash(k);
        //Get the object under the current array subscript
        Entry entry = table[index];
        //Determine if the current object contains data
        if (entry == null){
            //Insert data into the array at the index position
            table[index] = new  Entry<K,V>(k,v,index,null);
            //size+1 for each additional data
            //Store inside the old data method next
            table[index] = new  Entry<K,V>(k,v,index,entry);
        return (V) table[index].getValue();

     * Method of calculating array subscripts by passing in key value
     * @param k
     * @return
    private int hash(K k) {
        int i = k.hashCode()%16;
        if (i >= 0){
            return i;
            return -i;

     * 1.hash with key to calculate array subscript index
     * 2.Find entry object by index
     * 3.Determine whether the entry object is empty or not: Return directly without finding the corresponding data
     * 4.Not empty: Determines if the key is equal to the key in the object: returns value
     * 5.Unequal: Determine whether the next is empty, or if not, whether the key in the next is equal to the key to be found until it is equal before returning or empty
     * @param k
     * @return
    public V get(K k) {
        //First determine if there is any data in the map
        if(size == 0){
            //Return empty if not saved
            return null;
        //Get the subscript, index value by hash algorithm
        int index = hash(k);
        //Find a matching entry value using the findValue method
        Entry<K,V> entry = findValue(table[index] , k);
        //Determine if the entry value is empty
        if(entry != null){
            //Return Value
            return (V) entry.getValue();
        return null;

     * Recursively implementing a chain table to find entry objects that meet the requirements
     * Otherwise, an entry object is returned
     * Irregular returns null
     * @param entry
     * @param k
     * @return
    private Entry<K,V> findValue(Entry<K,V> entry ,K k) {
        //Determine if k is equal to the key value in the entry object
        if (k.equals(entry.getKey())|| k == entry.getKey()){
            //Equality returns directly
            return entry;
            //Otherwise execute else
        }else {
            //Determine if the list also contains data
            if (entry.next != null){
                //Recursively find values that match
                return   findValue(entry.next,k);
        return null;

    public int size() {
        return size;

    //Entry Implementation Class
    class Entry<K,V> implements Map.Entry<K,V>{

        K k;

        V v;

        //Computed hash value (index)
        int hash;

        Entry<K,V> next;

        //Parametric construction method
        public Entry(K k, V v, int hash, Entry<K, V> next) {
            this.k = k;
            this.v = v;
            this.hash = hash;
            this.next = next;

        public Object getKey() {
            return k;

        public Object getValue() {
            return v;

  Finally, build a test class to test our HashMap   put   and   get   Method

package com.guozm.waimai1.hashmap;

//Test Class
public class HashTest {

    //Main method
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("Map","Map Interface");
        map.put("HashMap","Realization Map Interface");
        map.put("HashTest","Map Test Class");


  Run Results

  Here we have written a simple HashMap.

Why iiii JDK8 Introduced Red and Black Trees

If we have a lot of data, after all, HashMap is only 16 sizes, there will be a lot of data under an index, that is, the chain length will be very long, when we want to find data in the chain table, we have to traverse the entire chain table. Time efficiency is low. So adding red and black trees to JDK8 is to optimize this. (Personal understanding, welcome communication if there are any errors)

Tags: Java data structure source code HashMap IDEA

Posted on Mon, 01 Nov 2021 13:27:04 -0400 by coder_