zoukankan      html  css  js  c++  java
  • HashMap是无序的

    一、 说明

    HashMap是基于哈希表Map的实现。设计初衷主要是为了解决键值(key-value)对应关联的,HashMap的优势是可以很快的根据键(key)找到该键对应的值(value),但是我们在使用的过程中需要注意一下,HashMap是一种无序的存储结构。HashMap的实现是假定元素是放在一个圆形的环上,每次put进来的元素根据其hashCode计算该元素在圆环上索引,把该元素放到合适的位置。

    二、 Put和get关键方法

    public V put(K key, V value) {

    if (key == null)

    return putForNullKey(value);

    当传入的key为null时,则直接调用putForNullKey方法,在索引为0的位置压入该value值,这也就是HashMap为什么支持压入null值。

    int hash = hash(key.hashCode());

    int i = indexFor(hash, table.length);

    这两个方法是很牛X的地方,第一个方法是根据key的hashCode利用hash方法生成一个hash值,然后通过indexFor函数获取table的索引值。

    是的,没错,HashMap就是通过table的结构来存储数据的。HashMap最牛X的地方是能根据hash值计算出正确的索引,比较深奥。下面是put的整个方法:

    public V put(K key, V value) {

    if (key == null)

    return putForNullKey(value);

    int hash = hash(key.hashCode());

    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;

    }

    实际上,如果插入的数据在HashMap中已经存在,则调用put函数的时候会返回oldValue。当我们在使用get函数的时候,同样是根据key的hashCode,从table中的对应索引位置提取该值并返回。

    到这里,我们可以看到HashMap是通过key的hashCode来计算索引的,与元素放入的先后顺序没有什么关系,所以我们在使用HashMap的时候,千万不要寄希望于HashMap中的数据与我们压入的数据的先后顺序一致。如果要保证压入的顺序一致,可以使用LinkedHashMap对象。

    三、 HashMap与HashTable的区别

    1. HashMap允许put进来一个null元素,HashTable则不允许,put进来null值后抛异常

    2. HashMap的一些操作(如put)没有同步,而HashTable的很多操作都是加上同步操作(增加了synchronized关键字)

  • 相关阅读:
    二进制安全的一些基础知识
    栈溢出笔记-第五天
    一次基于白盒的渗透测试
    栈溢出笔记-第四天
    Hadoop1-认识Hadoop大数据处理架构
    Kubernetes1-K8s的简单介绍
    Docker1 架构原理及简单使用
    了解使用wireshark抓包工具
    Linux系统设置开机自动运行脚本的方法
    Mariadb/Mysql 主主复制架构
  • 原文地址:https://www.cnblogs.com/cl1024cl/p/6205550.html
Copyright © 2011-2022 走看看