理解HashMap底层原理,一个简单的HashMap例子

package com.jl.testmap;

/**
 *  自定义一个HashMap
 * @author JiangLai
 *
 */
public class MyHashMap<K,V> {

    Node<K,V>[] table;//位桶数组
    int size;//存放键值对的个数

    public MyHashMap() {
        table = new Node[16];//长度一般定义为2的整数次幂
    }

    public void put(K key,V value) {

        //定义新的节点对象
        Node newNode = new Node();
        newNode.hash = myHash(key.hashCode(), table.length);
        newNode.key = key;
        newNode.value = value;
        newNode.next = null;

        Node temp = table[newNode.hash];

        Node itorLast  = null;//正在遍历的最后一个元素

        if(temp==null) {
            //此处数组元素为空,则直接将新节点放入
            table[newNode.hash] = newNode;
            size++;
        }else {
            //此处数组元素 不为空,则遍历整个链表
            while (temp!=null) {
                //判断key是否重复,相同则替换,
                if(temp.key.equals(key)) {
                    temp.value = value;//只是覆盖value即可,其他的值不变。(hash,key,next)
                    break;
                }else {//如果不重复,则遍历下一个
                    itorLast = temp;
                    temp = temp.next;
                }

            }

            if(itorLast!=null) {
                itorLast.next = newNode;
                size++;
            }
        }
    }

    public V get(K key) {

        int hash = myHash(key.hashCode(), table.length);

        Object value = null;

        if(table[hash] != null) {
            Node<K,V> temp = table[hash];
            while (temp!=null) {
                if(temp.key.equals(key)) {//如果相等,则返回对应的值
                    value = temp.value;
                    break;
                }else {
                    temp = temp.next;
                }
            }
        }

        return (V)value;
    }

    //计算Hash值
    public int myHash(int v,int length) {
        //二者作用一样
//        System.out.println(v&(length-1));//直接位运算,效率高.
//        System.out.println(v%(length-1));//取余运算,效率低.
        return v&(length-1);
    }

    @Override
    public String toString() {
        //{10:aa,20:bb}
        StringBuilder sb = new StringBuilder("{");

        //遍历数组
        for(int i=0;i<table.length;i++) {
            Node<K,V> temp = table[i];//当前元素
            //遍历链表
            while (temp!=null) {
                //当前元素的key和value
                sb.append(temp.key+":"+temp.value+",");
                //当前元素的下一个元素
                temp = temp.next;
            }
        }

        sb.setCharAt(sb.length()-1, ‘}‘);

        return sb.toString();
    }

    public static void main(String[] args) {
        MyHashMap<Integer,String> map01 = new MyHashMap<>();
        map01.put(10, "001");
        map01.put(20, "002");

        System.out.println(map01);

        System.out.println(map01.get(10));
    }

}
package com.jl.testmap;

/**
 * 用于TestHashMap中
 * @author JinagLai
 */
public class Node<K,V> {

     int hash;//HashCode
     K key;//键
     V value;//值
     Node<K,V> next;//下一个节点

}

原文地址:https://www.cnblogs.com/JiangLai/p/10083507.html

时间: 2024-10-28 14:16:29

理解HashMap底层原理,一个简单的HashMap例子的相关文章

HashMap底层原理分析(put、get方法)

1.HashMap底层原理分析(put.get方法) HashMap底层是通过数组加链表的结构来实现的.HashMap通过计算key的hashCode来计算hash值,只要hashCode一样,那hash值就是相同的.当hash值相同时,就会出现hash冲突,HashMap通过链表来解决冲突. 原理图: 实例: import java.util.HashMap; import java.util.Map; ? public class HashMapTest { public static vo

使用Multiplayer Networking做一个简单的多人游戏例子-2/3(Unity3D开发之二十六)

猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51007512 使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Networking做一个简单的多人游戏例子-3/3 7. 在网络中控制Player移动 上一篇中,玩家操

一个简单的KVO例子

一个简单的KVO例子. 两个界面,第一个界面显示名字和配偶(spouse)名字,第二个界面显示修改名字和配偶名字,返回时,将看到第一个界面的名字显示发生改变. 首先定义一个person类作为model. #import <Foundation/Foundation.h> @interface Person : NSObject @property (strong, nonatomic) NSString *name; @property (strong, nonatomic) NSString

Java一个简单的死锁例子

内容:一个简单的死锁例子,大概的思路:两个线程A和B,两把锁X和Y,现在A先拿到锁X,然后sleep()一段时间,我们知道sleep()是不会释放锁资源的.然后如果这段时间线程B拿到锁Y,也sleep()一段时间的话,那么等到两个线程都醒过来的话,那么将互相等待对方释放锁资源而僵持下去,陷入死锁.flag的作用就是让A和B获得不同的锁. public class TestDeadLock { public void run() { MyThread mt = new MyThread(); ne

编写一个简单的jdbc例子程序

1 package it.cast.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 9 public class Base { 10 11 public static void main(String[] args) th

一个简单的小例子让你明白c#中的委托-终于懂了!

模拟主持人发布一个问题,由多个嘉宾来回答这个问题. 分析:从需求中抽出Host (主持人) 类和Guests (嘉宾) 类. 作为问题的发布者,Host不知道问题如何解答.因此它只能发布这个事件,将事件委托给多个嘉宾去处理.因此在Host 类定义事件,在Guests类中定义事件的响应方法.通过多番委托的"+="将响应方法添加到事件列表中,最终 Host 类将触发这个事件.实现过程如下: 代码其实很少下面贴出来所有代码: QuestionArgs.cs view plaincopy to

一个简单的cmake例子

一个简单的cmake例子CMakeLists.txt,生成动态库文件,可以指定发布目录. 尚不支持: 1.交叉编译环境配置 2.添加依赖库 1 #在当前目录新建一个build目录,然后cd build:cmake .. 2 #这样的好处是,可以将cmake生成的内容,和源码文件分离 3 4 #定义好版本需求 5 cmake_minimum_required (VERSION 2.6) 6 #工程名字 7 project (Libtree) 8 #编译结果发布路径 9 set ( CMAKE_IN

面试官再问你 HashMap 底层原理,就把这篇文章甩给他看

前言 HashMap 源码和底层原理在现在面试中是必问的.因此,我们非常有必要搞清楚它的底层实现和思想,才能在面试中对答如流,跟面试官大战三百回合.文章较长,介绍了很多原理性的问题,希望对你有所帮助~ 目录 本篇文章主要包括以下内容: HashMap 的存储结构 常用变量说明,如加载因子等 HashMap 的四个构造函数 tableSizeFor()方法及作用 put()方法详解 hash()方法,以及避免哈希碰撞的原理 resize()扩容机制及原理 get()方法 为什么HashMap链表会

hashmap底层原理

从大的方向上来说,hashmap底层其实是采用数组+链表+红黑树的形式. 在数据插入过程中,随着数据量的增大,hashmap里通过数组扩容,链表转红黑树形式来存储数据的. 那么,数组扩容是什么时候进行扩容的呢? 其实,数组扩容是根据数组阈值来判定是否扩容,hashmap设定初始数组的个数默认是16个,而阈值则通过初始数组个数X默认加载因子0.75, 超过该阈值时,则链表(单链表)则转化为红黑树. hashmap的put过程: 在put的时候,是先根据存入hashmap的key计算出其hash值的

[python] 理解metaclass并实现一个简单ORM框架

metaclass 除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass. metaclass,直译为元类,简单的解释就是: 当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例. 但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类. 连接起来就是:先定义metaclass,就可以创建类,最后创建实例. 所以,metaclass允许你创建类或者修改类.换句话说,你可以把类看成是met