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就会报错.

JVM里面hashtable和hashmap实现原理的更多相关文章

  1. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  2. (转)HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  3. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)

    HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别 文章来源:http://www.cnblogs.com/beatIteWeNerverGiveU ...

  4. [转帖]HashMap、HashTable、ConcurrentHashMap的原理与区别

    HashMap.HashTable.ConcurrentHashMap的原理与区别 http://www.yuanrengu.com/index.php/2017-01-17.html 2017年1月 ...

  5. HashMap、Hashtable、ConcurrentHashMap的原理与区别

    同步首发:http://www.yuanrengu.com/index.php/2017-01-17.html 如果你去面试,面试官不问你这个问题,你来找我^_^ 下面直接来干货,先说这三个Map的区 ...

  6. HashMap、Hashtable、ConcurrentHashMap的原理与区别(简述)

    HashTable 底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相 ...

  7. 面试必备:HashMap、Hashtable、ConcurrentHashMap的原理与区别

    同步首发:http://www.yuanrengu.com/index.php/2017-01-17.html 如果你去面试,面试官不问你这个问题,你来找我^_^ 下面直接来干货,先说这三个Map的区 ...

  8. Hashmap与Hashtable的区别及Hashmap的原理

    Hashtable和HashMap有几个主要的不同:线程安全以及速度.仅在你需要完全的线程安全的时候使用Hashtable,而如果你使用Java 5或以上的话,请使用ConcurrentHashMap ...

  9. 集合 HashMap 的原理,与 Hashtable、ConcurrentHashMap 的区别

    一.HashMap 的原理 1.HashMap简介 简单来讲,HashMap底层是由数组+链表的形式实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表 ...

随机推荐

  1. python--介绍

    语言类型介绍 编译与解释理解: 打个比方:假如你打算阅读一本外文书,而你不知道这门外语,那么你可以找一名翻译,给他足够的时间让他从头到尾把整本书翻译好,然后把书的母语版交给你阅读:或者,你也立刻让这名 ...

  2. JS实现字符串去重,数组去重

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. oracle的sql函数

    只读事务set transaction read only当一个用户添加了只读事务,则查询时只会查到设置只读事务之前的内容,在并发量大的系统中,通过设置只读事务 便于统计 oracle的sql函数的使 ...

  4. 主流存储引擎详解:Innodb,Tokudb、Memory、MYISAM、Federated

    主流存储引擎: Innodb:推荐使用,主力引擎,使用99%以上的场景 Tokudb:高速写入使用,日用量大量写入eg:500G可压缩为50G.适用于访问日志的写入,相对MYISAM有事务性,相对于I ...

  5. [转载]“java.sql.SQLException:指定了无效的 Oracle URL”

    原文地址:"java.sql.SQLException:指定了无效的 Oracle URL"作者:康愚 昨天晚上用MyEclipse连接Oracle,出现了" java. ...

  6. Spring 的@Controller 和@RestController的区别

    @RestController Spring 4.0中新增的特性 @RestController 继承自 @Controller,相当于@ResponseBody + @Controller   1. ...

  7. hihocoder 1186

    1186 : Coordinates 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Give you two integers P and Q. Let all div ...

  8. 【转】monkeyrunner学习总结二:连接、安装、启动

    一.获取packageName与startActivity 前置条件:已成功安装配置SL4A并连接PC调试(参见:monkeyrunner学习总结一:环境搭建:http://www.amsoft.cn ...

  9. Exchanger, Changing data between concurrent tasks

    The Java concurrency API provides a synchronization utility that allows the interchange of data betw ...

  10. spark stream初探

    spark带了一个NetworkWordCount测试程序,用以统计来自某TCP连接的单词输入: /usr/local/spark/bin/run-example streaming.NetworkW ...