关于java中的HashMap,我们在项目中经常使用到,但是我们的场景是否使用对了呢?

  下面分为四个部分来阐述我的HashMap的理解

  1、为什么要使用hashMap?

  在项目中,需求的实现需要使用到一些数据结构来保存key-value形式的数据,也就是说hashMap其实就是一个装载数据的容器。例如,我需要查询水果的价格,那么很自然就会想到将这些数据存放在一个hashMap里面,苹果:9.88/kg,雪梨:5/kg,香蕉:5/kg,榴莲:26/kg,当我问榴莲的价格的时候,很快就知道了是26/kg。

  2、hashMap的使用场景有哪些?

  jdk里面是这么说的:

Hash table based implementation of the <tt>Map</tt> interface.  This
* implementation provides all of the optional map operations, and permits
* <tt>null</tt> values and the <tt>null</tt> key. (The <tt>HashMap</tt>
* class is roughly equivalent to <tt>Hashtable</tt>, except that it is
* unsynchronized and permits nulls.) This class makes no guarantees as to
* the order of the map; in particular, it does not guarantee that the order
* will remain constant over time.
  也就是说基于Map接口实现、允许null键/值、非同步、不保证有序(比如插入的顺序)、也不保证顺序不随时间变化。
  当你需要一个效率高,不需要线性安全的map对象的时候,就可以使用hashMap

  3、源码(1.7)探索

  put方法:a)、检查存放的table是否为空,如果为空,则初始化,默认加载因子为0.75,table初始大小为16

       b)、检查key是否为空

       c)、计算key的hash值,确认key在table中的位置

       d)、因为hashMap是由数组+链表实现的,需要判断table[i]中链表的元素和key是否相等,找到将老值替换为新值,然后返回。

       e)、如果table[i]的元素为空,则新增一个元素,当table中的元素大小大于 capacity * loadFactor,则需要调整table的大小了,为原来的2倍,这个时候会进行数组拷贝,比较耗性能,所以如果初始化容器的时候,可以确认容器的大小,就最好直接初始化对应的table大小,不需要进行扩容

 public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
} modCount++;
addEntry(hash, key, value, i);
return null;
}

get 方法:和put方法差不多,都是先计算hash值,然后获取table[i]链表中的数据

final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
} int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}

  4、使用的设计模式

   无

  5、可能会出现的坑

    在多线程环境中使用hashMap可能会出现cpu打到100%的异常,就是死循环的情况,原因是resize的时候,拷贝对象引用出现循环引用

jdk-map-hashMap的更多相关文章

  1. Collections+Iterator 接口 | Map+HashMap+HashTable+TreeMap |

    Collections+Iterator 接口 1. Collections 是一个操作 Set.List 和 Map 等集合的工具类 Collections 中提供了大量方法对集合元素进行排序.查询 ...

  2. ES6 & Map & hashMap

    ES6 & Map & hashMap 01 two-sum https://leetcode.com/submissions/detail/141732589/ hashMap ht ...

  3. Map HashMap 排序 迭代循环 修改值

    HashMap dgzhMap = Dict.getDict("dgzh"); Iterator it_d = dgzhMap.entrySet().iterator(); whi ...

  4. Map随笔:最常用的Map——HashMap

    目录 Map随笔:最常用的Map--HashMap 前言: 1,HashMap的结构 2,HashMap的一些属性(JDK8) 3,HashMap的构造函数(JDK8) 4,HashMap的一些方法( ...

  5. java多线程:并发包中ConcurrentHashMap和jdk的HashMap的对比

    一:HashMap--->底层存储的是Entry<K,V>[]数组--->Entry<K,V>的结构是一个单向的链表static class Entry<K, ...

  6. [Java] Map / HashMap - 源代码学习笔记

    Map 1. 用于关联 key 和 value 的对象,其中 key 与 key 之间不能重复. 2. 是一个接口,用来代替 Java 早期版本中的 Dictionary 抽象类. 3. 提供三种不同 ...

  7. 走进JDK(十)------HashMap

    有人说HashMap是jdk中最难的类,重要性不用多说了,敲过代码的应该都懂,那么一起啃下这个硬骨头吧!一.哈希表在了解HashMap之前,先看看啥是哈希表,首先回顾下数组以及链表数组:采用一段连续的 ...

  8. jdk 8 HashMap源码解读

    转自:https://www.cnblogs.com/little-fly/p/7344285.html 在原来的作者的基础上,增加了本人对源代码的一些解读. 如有侵权,请联系本人 这几天学习了Has ...

  9. 高并发第九弹:逃不掉的Map --> HashMap,TreeMap,ConcurrentHashMap

    平时大家都会经常使用到 Map,面试的时候又经常会遇到问Map的,其中主要就是 ConcurrentHashMap,在说ConcurrentHashMap.我们还是先看一下, 其他两个基础的 Map ...

  10. Map / HashMap 获取Key值的方法

    方法1:keySet()HashMap hashmp = ne HashMap();hashmp.put("aa", "111");Set set = hash ...

随机推荐

  1. (2015年郑州轻工业学院ACM校赛题)I 旋转图像

    矩阵旋转,写一个转 90° 的函数就行了, 注意每次要将 长和宽的值进行交换就行了. #include<stdio.h> #include<iostream> #include ...

  2. 关于JavaScriptSerializer使用的问题

    初学C#的同学们,你们有没有这样的问题:遇到不懂的问题,就到处搜索,好不容易搜索出来答案吧,却发现缺少引用,缺少引用就添加引用吧,结果在添加中找不到!是不是很恼火? 解决办法:查看项目的目标框架,如果 ...

  3. 【2013长沙区域赛】部分题解 hdu4791—4801

    1001: 签到题,二分一下即可 代码: #include <set> #include <map> #include <cmath> #include <c ...

  4. 关于xcode7编译旧项目崩溃-[UIApplication _runWithMainScene:transitionContext:completion:]

    崩溃原因 crash: Assertion failure in -[UIApplication _runWithMainScene:transitionContext:completion:], / ...

  5. <Win32_8>由浅入深——滚动条

    滚动条在Win32程序中是非常常见的一个控件,它的功能和地位也就不言而喻了,在文本输出中算是一个难点…… 我将借用P先生的思路讲述两种不同风格滚动条,下面切入主题:(实例程序都是显示一张位图  当然, ...

  6. qDebug 学习小结

    在qtcentre中看到有网友问这样一个问题: Why this doesn't work? qDebug() << "Test" << std::endl ...

  7. Java基础知识强化77:正则表达式之获取功能(Pattern 和 Matcher类的使用)

    1. 获取功能: Pattern 和 Matcher类结合使用 2. 使用案例: package cn.itcast_05; import java.util.regex.Matcher; impor ...

  8. LSI MegaCl i命令使用1

    MegaCli命令使用:cd /opt/MegaRAID/MegaCli/MegaCli -AdpAllInfo -aAll     [显示所有适配器信息]MegaCli -LDInfo -Lall ...

  9. MVC4数据访问EF查询linq语句的时候报错找不到表名问题

    一天做项目的时候遇到这样的问题,MVC4用EF访问数据查询用linq语句的时候报错找不到表名:报错如下图: 研究了几种情况,最后还是没有找到正真的问题所在,不过可能是和路由解析问题有关,暂时还没有进行 ...

  10. Cookies欺骗分析与防护

    今天来谈谈cookies欺骗是怎么回事以及如何避免. 用户在登录之后通常会保存用户信息,以便在其他需要权限的页面去验证用户信息是否具有访问权限. 有同学说我在登录的时候已经很注意SQL注入问题了,还有 ...