一、HashMap和Hashtable的区别

(1)HashMapl的键值(key)和值(value)可以为null,而Hashtable不可以

(2)Hashtable是线程安全类,而HashMap为非线程安全类(HashMap是非synchronized,而Hashtable是synchronized)

(3)由于Hashtable是线程安全,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。

源码解析

HasgMap

Hashtable

二、如何使HashMap线程安全

Map m = Collections.synchronizeMap(hashMap);

三、详解HashMap

HashMap两种声明方式

1. Map<String> hashMap = new HashMap<String>();
2. HashMap<String> hashMap = new HashMap<String>();

异同:

  优点:

①灵活,符合java中所倡导的面向接口编程,例如如果项目需求不继续使用HashMap,而是改成TreeMap时,可以Map<String> hashMap = new TreeMap<String>();

         ②第一种声明方式是:父类的引用指向子类的对象,是多态的一种表现形式,实现了多态,多态后就可以写出一段所有子类都通用的代码,当添加新的子类时,这段代码是不需要修改的。
父类的引用指向子类的对象的好处:多态、动态链接,向上转型。
缺点:
①无法调用HashMap特有的方法。

stackoverflow链接:http://stackoverflow.com/questions/1348199/

HashMap源码解析


链拉法


(1)put函数实现

①求key的hashcode(),然后再对key的hashcode求它的hash值

②如果发生Hash碰撞,则比较key值,如果还相等,以链表的形式放在同一个Bucket中,但不同Entry

③如果没发生Hash碰撞,直接放入Bucket中。

④ 如果binCount>=TREEIFY_THRESHOLD - 1,就会有链表编程红黑树(TREEIFY_THRESHOLD=8)

⑤如果节点存在(比较过hash与key),则直接覆盖旧value

⑥如果bucket达到临界值(超过load factor*current capacity),就进行扩容

 public V put(K key, V value) {
         return putVal(hash(key), key, value, false, true);
     }

 static final int hash(Object key) {
         int h;
         return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
     }

  static final int TREEIFY_THRESHOLD = 8;
 final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                    boolean evict) {
         Node<K,V>[] tab; Node<K,V> p; int n, i;
         if ((tab = table) == null || (n = tab.length) == 0)
             n = (tab = resize()).length;
//计算是哪一个bucket,并把头节点返回p if ((p = tab[i = (n - 1) & hash]) == null)
//如果该bucket为空,则新建节点,放入该bucket中 tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k;
//key先比较hash值,如果hash值相等,再比较key值,如果hash与key都相等,则覆盖 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p;
//如果实例p是TreeNode类型,则放进红黑树种 else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
//链表处理 else {
//通过循环来插入后续节点 for (int binCount = 0; ; ++binCount) {
//插入链表中,采用头插法,e = p.next,p.next=newNode,p = e; if ((e = p.next) == null) { p.next = newNode(hash, key, value, null);
//如果binCount>=7,就会有链表编程红黑树 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; }
//判断链表中是否循环到hash相同,key相同的Entry if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } }
//如果Hash值相同,且key相等,则覆盖 if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }
												

Java源码之HashMap的更多相关文章

  1. JAVA源码分析-HashMap源码分析(一)

    一直以来,HashMap就是Java面试过程中的常客,不管是刚毕业的,还是工作了好多年的同学,在Java面试过程中,经常会被问到HashMap相关的一些问题,而且每次面试都被问到一些自己平时没有注意的 ...

  2. Java源码学习:HashMap实现原理

    AbstractMap HashMap继承制AbstractMap,很多通用的方法,比如size().isEmpty(),都已经在这里实现了.来看一个比较简单的方法,get方法: public V g ...

  3. 浅析Java源码之HashMap

    写这篇文章还是下了一定决心的,因为这个源码看的头疼得很. 老规矩,源码来源于JRE1.8,java.util.HashMap,不讨论I/O及序列化相关内容. 该数据结构简介:使用了散列码来进行快速搜索 ...

  4. Java源码阅读HashMap

    1类签名与注释 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cl ...

  5. Java源码解析|HashMap的前世今生

    HashMap的前世今生 Java8在Java7的基础上,做了一些改进和优化. 底层数据结构和实现方法上,HashMap几乎重写了一套 所有的集合都新增了函数式的方法,比如说forEach,也新增了很 ...

  6. JAVA源码分析-HashMap源码分析(二)

    本文继续分析HashMap的源码.本文的重点是resize()方法和HashMap中其他的一些方法,希望各位提出宝贵的意见. 话不多说,咱们上源码. final Node<K,V>[] r ...

  7. 浅析Java源码之HashMap外传-红黑树Treenode(已鸽)

    (这篇文章暂时鸽了,有点理解不能,点进来的小伙伴可以撤了) 刚开始准备在HashMap中直接把红黑树也过了的,结果发现这个类不是一般的麻烦,所以单独开一篇. 由于红黑树之前完全没接触过,所以这篇博客相 ...

  8. 【数据结构】8.java源码关于HashMap

    1.hashmap的底层数据结构 众所皆知map的底层结构是类似邻接表的结构,但是进入1.8之后,链表模式再一定情况下又会转换为红黑树在JDK8中,当链表长度达到8,并且hash桶容量超过64(MIN ...

  9. java源码之HashMap和HashTable的异同

    代码版本 JDK每一版本都在改进.本文讨论的HashMap和HashTable基于JDK 1.7.0_67 1. 时间 HashTable产生于JDK 1.1,而HashMap产生于JDK 1.2.从 ...

随机推荐

  1. 芝麻HTTP:Appium的安装

    Appium是移动端的自动化测试工具,类似于前面所说的Selenium,利用它可以驱动Android.iOS等设备完成自动化测试,比如模拟点击.滑动.输入等操作,其官方网站为:http://appiu ...

  2. Python与Mongodb交互

    MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案 MongoDB 将数据存储为一个文档,数据结构由键值 ...

  3. Python基础__字符串拼接、格式化输出与复制

    上一节介绍了序列的一些基本操作类型,这一节针对字符串的拼接.格式化输出以及复制的等做做详细介绍.一. 字符串的拼接 a = 'I', b = 'love', c = 'Python'. 我们的目的是: ...

  4. Dynamics CRM中一个查找字段引发的【血案】

    摘要: 本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复267或者20180311可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyon ...

  5. xshell无法登录阿里云服务器

    1. 现象 a. 使用xshell无法登录服务器 b. 查看sshd服务 c. 不同公网ip的电脑正常登陆 2. 解决方案 a. 不同公网ip可以登录,断定是ip被黑名单,联系阿里云服务,把公网ip加 ...

  6. jquery的各种插件调用(有些已经过时,以备注,其他的一些可以闲的时候用作拆解)

    jquery的valiteDate验证插件应用 <!DOCTYPE html> <html>        < head>            < meta ...

  7. 【BZOJ3223】文艺平衡树(Splay)

    题面 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...

  8. 关于C++ const 的全面总结《转》

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类 ...

  9. 如何使用Vue

    我在学习前端框架的时候面临了很多的选择,比较流行的有react,angularJS,还有另外一个就是Vue,Vue相对于另外两个出现时间更晚,也更符合响应式(Reactive)组件化(Composab ...

  10. html onclick时间传字符串参数

    经常忘记拼html中onclick事件传字符串引号的问题,所以今天记一下! 简单一句话 外面是"",里面就是'',外边是'',里边就是"".   示例: var ...