当前位置: 首页 > news >正文

JVM里面hashtable和hashmap实现原理

JVM里面hashtable和hashmap实现原理

 
文章分类:Java编程

转载

 

在hashtable和hashmap是java里面常见的容器类,

是Java.uitl包下面的类,

那么Hashtable和Hashmap是怎么实现hash键值对配对的呢,我们看看jdk里面的源码,分析下Hashtable的构造方法,put(K, V)加入方法和get(Object)方法就大概明白了。

一、Hashtable的构造方法:Hashtable(int initialCapacity, float loadFactor)

    public Hashtable(int initialCapacity, float loadFactor) {
 if (initialCapacity < 0)
     throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal Load: "+loadFactor);

        if (initialCapacity==0)
            initialCapacity = 1;
 this.loadFactor = loadFactor;
 table = new Entry[initialCapacity];
 threshold = (int)(initialCapacity * loadFactor);
    }

这个里面米内有什么好说的,要注意的是table一个是实体数组,输入的initialCapacity表示这个数组的大小,而threshold 是一个int值,其中loadFactor默认是0.75,就是说明,当table里面的值到75%的阀值后,快要填满数组了,就会自动双倍扩大数字容 量。

   而Entry<K,V> 来自与

private static class Entry<K,V> implements Map.Entry<K,V> {
            int hash;
            K key;
            V value;
            Entry<K,V> next;
是一个单项链表,

上图就是Hashtable的表,

二、put(K, V)加入方法

    public synchronized V put(K key, V value) {
 // Make sure the value is not null
 if (value == null) {
     throw new NullPointerException();
 }

 // Makes sure the key is not already in the hashtable.
 Entry tab[] = table;
 int hash = key.hashCode();
 int index = (hash & 0x7FFFFFFF) % tab.length;
 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
     if ((e.hash == hash) && e.key.equals(key)) {
  V ld = e.value;
  e.value = value;
  return old;
     }
 }

 modCount++;
 if (count >= threshold) {
     // Rehash the table if the threshold is exceeded
     rehash();

            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
 }

 // Creates the new entry.
 Entry<K,V> e = tab[index];
 tab[index] = new Entry<K,V>(hash, key, value, e);
 count++;
 return null;
    }

这个看看起来很长,只要注意三点就可以了,

1.index,index是键值的hashcode和0x7FFFFFFF的&运算,然后根据数组长度求余值。这样可以定出所在队列名称,

2、

 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
     if ((e.hash == hash) && e.key.equals(key)) {
  V ld = e.value;
  e.value = value;
  return old;
     }
 }

for语句里面是让e在tab某个队列名为index单项链表里面遍历,第几个单项链表的定义由index定义,看看该队列是否已经有同样的值,如果有,就返回该值。

3、如果没有,则加入

 Entry<K,V> e = tab[index];
 tab[index] = new Entry<K,V>(hash, key, value, e);

三、get(Object),获得

    public synchronized V get(Object key) {
 Entry tab[] = table;
 int hash = key.hashCode();
 int index = (hash & 0x7FFFFFFF) % tab.length;
 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
     if ((e.hash == hash) && e.key.equals(key)) {
  return e.value;
     }
 }
 return null;
    }

这个就很好理解了 int index = (hash & 0x7FFFFFFF) % tab.length;

获得队列名称,

 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
     if ((e.hash == hash) && e.key.equals(key)) {
  return e.value;
     }
 }

在该队里面遍历,根据hash值获得具体值。

 

总结下,一个是根据index确定队列,在由hash值获得具体元素值。

 

看完了hashtable, 我们在来看看hashMap
hashMap可以算作是hashtable的升级版本, 最早从1.2开始有的. 

但是, 两者之间最主要的不同有两点.
1.     hashMap的读写是unsynchronized, 在多线程的环境中要注意使用
而hashtable是synchronized
这两者的不同是通过在读写方法上加synchronized关键字来实现的.

第二个不同是hashMap可以放空值, 而hashtable就会报错.

转载于:https://www.cnblogs.com/downey/p/4888405.html

相关文章:

  • iOS 10 的推送 User Notifications Framework
  • .NET连接MongoDB数据库实例教程
  • rar自动压缩备份
  • Java_BigDecimal类型比较大小
  • 小程序使用smart模板的方法
  • LoadRunner上传文件脚本
  • Android自定义view双缓存技术
  • Linux命令行下运行java.class文件
  • nmap入门之其他
  • 实现IOC功能的简单Spring框架
  • 如何将GridViewEX升级到UWP(Universal Windows Platform)平台
  • Windows环境下安装 mysql-8.0.11-winx64 遇到的问题解决办法
  • LinuxMint下Docker的安装部署和验证
  • Vue-cli / webpack 加载静态js文件的方法
  • python函数的动态传参.作用域与命名空间
  • [nginx文档翻译系列] 控制nginx
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • Android 控件背景颜色处理
  • CEF与代理
  • express如何解决request entity too large问题
  • JS题目及答案整理
  • JS专题之继承
  • overflow: hidden IE7无效
  • PAT A1120
  • Sequelize 中文文档 v4 - Getting started - 入门
  • SwizzleMethod 黑魔法
  • Transformer-XL: Unleashing the Potential of Attention Models
  • ucore操作系统实验笔记 - 重新理解中断
  • ViewService——一种保证客户端与服务端同步的方法
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 你不可错过的前端面试题(一)
  • 手写一个CommonJS打包工具(一)
  • 在weex里面使用chart图表
  • 白色的风信子
  • 第二十章:异步和文件I/O.(二十三)
  • #if 1...#endif
  • %check_box% in rails :coditions={:has_many , :through}
  • (1)常见O(n^2)排序算法解析
  • (1)虚拟机的安装与使用,linux系统安装
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (4)Elastix图像配准:3D图像
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (第二周)效能测试
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (九)c52学习之旅-定时器
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (一)RocketMQ初步认识
  • .NET gRPC 和RESTful简单对比
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .net 流——流的类型体系简单介绍
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • .NET序列化 serializable,反序列化
  • :=
  • @Autowired @Resource @Qualifier的区别