public void put(K key, V value) {

        //if hashmap size is more than a certain load
        //its time to rehash the array
        if(size >= max_size*loadFactor ){
            //double the max_size
            max_size *= 2;
            //temporarily copy the old array
            Entry []temp = new Entry[max_size];
            System.arraycopy(store, 0, temp, 0, store.length);
            // create a clean copy of expanded old array
            store = new Entry[max_size];
            //reset the size of old array
            size = 0;

            //iterate the temporary copy and put all the values back in expanded old array
            for(int i=0; i<max_size/2; i ++){

                Entry<K,V> node = temp[i];
                //there could be a linked list inside
                while(node!=null){
                    //recursively call put
                    put(node.key, node.value);
                    node = node.next;
                }
            }
        }

        //trick to avoid negative hash code and hash value more than Integer.MAX_VALUE
        int hashcode = key.hashCode();
        int index = (hashcode & 0x7fffffff) % max_size;

        if(store[index]!=null){
            Entry<K,V> target = store[index];
            //update the value scenario
            while(target!=null){
                if(target.key.equals(key) && target.hashcode == hashcode){
                    target.value = value;
                    return;
                }
                target = target.next;
            }
            // create new entry
            Entry<K,V> newEntry = new Entry(hashcode,key,value,store[index]);
            store[index] = newEntry;
            size ++;

        } else {
            Entry<K,V> newEntry = new Entry(hashcode,key,value,null);
            store[index] = newEntry;
            size ++;
        }

    }