jdk-map-hashMap

  关于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大小,不需要进行扩容

 1 public V put(K key, V value) {
 2         if (table == EMPTY_TABLE) {
 3             inflateTable(threshold);
 4         }
 5         if (key == null)
 6             return putForNullKey(value);
 7         int hash = hash(key);
 8         int i = indexFor(hash, table.length);
 9         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
10             Object k;
11             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
12                 V oldValue = e.value;
13                 e.value = value;
14                 e.recordAccess(this);
15                 return oldValue;
16             }
17         }
18
19         modCount++;
20         addEntry(hash, key, value, i);
21         return null;
22     }

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的时候,拷贝对象引用出现循环引用

时间: 2024-11-05 11:00:14

jdk-map-hashMap的相关文章

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

Collections+Iterator 接口 1. Collections 是一个操作 Set.List 和 Map 等集合的工具类 Collections 中提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了对集合对象设置不可变.对集合对象实现同步控制等方法 排序操作: reverse(List):反转 List 中元素的顺序 shuffle(List):对 List 集合元素进行随机排序 sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序 sort(Li

Map HashMap 排序 迭代循环 修改值

HashMap dgzhMap = Dict.getDict("dgzh"); Iterator it_d = dgzhMap.entrySet().iterator(); while (it_d.hasNext()) { Map.Entry entry_d = (Map.Entry) it_d.next(); Object key = entry_d.getKey(); Object value = entry_d.getValue(); value = value.toString

JDK之HashMap、HashSet分析

HashMap主要分析key.value的放入Map和取出Map操作以及他的遍历器.个人觉得在HashMap中有个很重要的内部类Entry,Map的put,get等重要方法都是依靠这个Entry的.先来分析下这个内部类Entry,Entry中有几个重要的变量key.value.next,不用说大家也会明白这几个变量的含义,当然也自然会有get和set方法了.当我们在遍历Map的时候,有一种方法就是获取这个内部类的对象entry,然后去这个entry中取值.现在就以这个为例,遍历一个Map.首先获

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

一:HashMap--->底层存储的是Entry<K,V>[]数组--->Entry<K,V>的结构是一个单向的链表static class Entry<K,V> implements Map.Entry<K,V> {        final K key;        V value;        Entry<K,V> next;        int hash; /**         * Creates new entry.

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

Map 1. 用于关联 key 和 value 的对象,其中 key 与 key 之间不能重复. 2. 是一个接口,用来代替 Java 早期版本中的 Dictionary 抽象类. 3. 提供三种不同的视图用于观察内部数据,key 的 Set 视图.value 的 Collection 视图,key-value 关联对象的 Set 视图. 4. 有些实现会保证元素的顺序,例如 TreeMap.有些则不会保证,例如 HashMap 5. 如果 key 是可变对象,需要小心处理 6. key 值指向

Map:HashMap和TreeMap

一.Map集合     特点:将键映射到值得对象 Map集合和Collection集合的区别? Collection:是单列集合,存储的是单独出现的元素    Map: 是双列集合,存储的是键值对形式的元素 遍历方式:       方式一:通过键获取值                 hm.keySet();                 get(key)      方式二:通过键值对对象获取 键和值                hm.entrySet();               ge

JAVA集合------Map (HashMap实现)

package java_util_map; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class MapTest01 { public static void main(String[] args) { /*  * Map是一个接口,HashMap是Map的一个实现类  

java jdk 中HashMap的源码解读

HashMap是我们在日常写代码时最常用到的一个数据结构,它为我们提供key-value形式的数据存储.同时,它的查询,插入效率都非常高. 在之前的排序算法总结里面里,我大致学习了HashMap的实现原理,并制作了一个简化版本的HashMap. 今天,趁着项目的间歇期,我又仔细阅读了Java中的HashMap的实现. HashMap的初始化: Java代码 public HashMap(int initialCapacity, float loadFactor) public HashMap(i

Map...---HashMap和Hashtable的区别-----...LinkedHashMap

*Map接口不是Collection接口的子接口 *Map存放数据的方式采用键值对的方式,类似与生活中目录(键)和内容(值) *常见的实现类: * HashMap**:采用键-值对的方式进行存放. * 键(键的集合是就是set集合):唯一,无序,如果键重复,将发生覆盖 * 值:无序 不唯一(Collection) * 构造函数: * HashMap() 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap. * HashMap(int initialCapaci

Map/HashMap 获取Key值的方法

1.通过  KeySet()方法 Map<String,Student> newmap = new HashMap<String,Student>(); //newmap HaspMap类型的集合 有唯一的Key,一个Key对应相应的学生 Student stu = new Student("11","Mary","79"); //创建一个学生对象 学号11; 姓名 Mary 成绩 79 newmap.put("