什么是Map?

Map的三个特点

1.包含键值对 
2.键唯一 
3.键对应的值唯一

一:hash

什么是Hash

Hash,也可以称为“散列”,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。这是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出(也就是多对一的关系)。

HashMap

HashMap内部是使用一个默认容量为16的数组来存储数据的,而数组中每一个元素却又是一个链表的头结点,所以,更准确的来说,HashMap内部存储结构是使用哈希表的拉链结构(数组+链表),这种存储数据的方法叫做拉链法 。如图:

且每一个结点都是Entry类型,那么Entry是什么呢?我们来看看HashMap中Entry的属性:

 final K key;  
final V value;  
final int hash;  
HashMapEntry<K, V> next;  

从中我们得知Entry存储的内容有key、value、hash值、和next下一个Entry,那么,这些Entry数据是按什么规则进行存储的呢?就是通过计算元素key的hash值,然后对HashMap中数组长度取余得到该元素存储的位置,计算公式为hash(key)%len,比如:假设hash(14)=14,hash(30)=30,hash(46)=46 我们对len取余,得到hash(14)%16=14,hash(30)%16=14,hash(46)%16=14。所以hash值为14的这个元素存储在数组下标为14的位置。

从中可以看出,如果有多个元素key的hash值相同的话,后一个元素并不会覆盖上一个元素,而是采取链表的方式,把之后加进来的元素加入链表末尾,从而解决了hash冲突的问题,由此我们知道HashMap中处理hash冲突的方法是链地址法。

在此补充一个知识点,处理hash冲突的方法有以下几种:

  1. 开放地址法
  2. 再哈希法
  3. 链地址法
  4. 建立公共溢出区

讲到这里,重点来了,我们知道HashMap中默认的存储大小就是一个容量为16的数组,所以当我们创建出一个HashMap对象时,即使里面没有任何元素,也要分别一块内存空间给它,而且,我们再不断的向HashMap里put数据时,当达到一定的容量限制时(这个容量满足这样的一个关系时候将会扩容:HashMap中的数据量>容量*加载因子,而HashMap中默认的加载因子是0.75),HashMap的空间将会扩大,而且扩大后新的空间一定是原来的2倍,我们可以看put()方法中有这样的一行代码:

 int newCapacity = oldCapacity * 2;

所以,只要一满足扩容条件,HashMap的空间将会以2倍的规律进行增大。假如我们有几十万、几百万条数据,那么HashMap要存储完这些数据将要不断的扩容,而且在此过程中也需要不断的做hash运算,这将对我们的内存空间造成很大消耗和浪费,而且HashMap获取数据是通过遍历Entry[]数组来得到对应的元素,在数据量很大时候会比较慢,所以在Android中,HashMap是比较费内存的。

所以我们在一些情况下可以使用SparseArray和ArrayMap来代替HashMap。

二:ArrayMap

ArrayMap是一个<key,value>映射的数据结构,它设计上更多的是考虑内存的优化,内部是使用两个数组进行数据存储,一个数组记录key的hash值,另外一个数组记录Value值,它和SparseArray一样,也会对key使用二分法进行从小到大排序,在添加、删除、查找数据的时候都是先使用二分查找法得到相应的index,然后通过index来进行添加、查找、删除等操作,所以,应用场景和SparseArray的一样,如果在数据量比较大的情况下,那么它的性能将退化至少50%。

ArrayMap方法:

public V put(K key, V value)

public V get(Objectkey)

public V remove(Objectkey)

public K keyAt(int index) 

public V valueAt(int index)

ArrayMap应用场景

  • 1.数据量不大,最好在千级以内
  • 2.数据结构类型为Map类型

欢迎大家关注公众号,不定时干货,只做有价值的输出

作者:Dawnzhang 
出处:https://www.cnblogs.com/clwydjgs/
版权:本文版权归作者
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任

ArrayMap和HashMap区别的更多相关文章

  1. ArrayMap 和HashMap的区别

    在以往android开发中,我们常常用key-value存储数据时,随手就会打出HashMap的代码,当数据量较小时,这种方法还不错还可以,当数据量比较多的时候,如果是PC机上,也还阔以.但是如果使用 ...

  2. Java中List,ArrayList、Vector,map,HashTable,HashMap区别用法

    Java中List,ArrayList.Vector,map,HashTable,HashMap区别用法 标签: vectorhashmaplistjavaiteratorinteger ArrayL ...

  3. Hashtable和HashMap区别

    Hashtable和HashMap区别 相同点: 实现原理,功能相同,可以互用 主要区别: a.hashtable继承Directionary类,HashMap实现Map接口 b.Hashtable线 ...

  4. [转]合理使用ArrayMap代替HashMap

    合理使用ArrayMap代替HashMap 2016年07月08日 15:34:44 阅读数:5938 转载请标注: 披萨大叔的博客 http://blog.csdn.net/qq_27258799/ ...

  5. Android内存优化(使用SparseArray和ArrayMap代替HashMap)

    在Android开发时,我们使用的大部分都是Java的api,比如HashMap这个api,使用率非常高,但是对于Android这种对内存非常敏感的移动平台,很多时候使用一些java的api并不能达到 ...

  6. Android内存优化(使用SparseArray和ArrayMap取代HashMap)

    在Android开发时,我们使用的大部分都是Java的api,比方HashMap这个api,使用率非常高,可是对于Android这样的对内存非常敏感的移动平台,非常多时候使用一些java的api并不能 ...

  7. LinkedHashMap和HashMap区别

    import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.uti ...

  8. Hashtable与HashMap区别(2)

    提到hashtable,先要澄清两个问题hashCode与equals().Hashtable有容量和加载因子,容量相当于桶,因子相当于桶里的对象.而hashCode我们可以把它理解为桶的序号,所以H ...

  9. 【Java】HashTable和HashMap区别

    ①继承不同 public class Hashtable extends Dictionary implements Map public class HashMap extends Abstract ...

随机推荐

  1. Django--多对多表操作/通过母版渲染页面

    目录 Django--多对多表操作+母版 需求 步骤 添加路由映射关系 老师表的增删改查 ajax操作老师表 Django--多对多表操作+母版 今天还以一个学生管理系统为例,先通过pymysql这个 ...

  2. UIPath RPA 自动化脚本 机器人从入门到精通

    本文链接:https://blog.csdn.net/qq_27256783/article/details/93619818 一.UiPath介绍 UiPath 是RPA(Robotic Proce ...

  3. 当前标识(IIS APPPOOL\DefaultAppPool)没有对“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files”的写访问权限

    找到或增加这个目录,给他增加权限.

  4. 【总结】web工作代码分类整理(持续更新)

    文件.blob 文件下载失败,将Blob对象转换为Json,处理异常错误? 使用FileReader,核心代码: var reader = new FileReader() reader.onload ...

  5. Python 之 计算psnr和ssim值

    基于python版的PSNR和ssim值计算 总所周知,图像质量评价的常用指标有PSNR和SSIM等,本博文是基于python版的图像numpy的float64格式和uint8格式计算两种指标值(附代 ...

  6. Odoo中的domain

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826127.html 一:domain表达式 domain表达式:通常用来筛选数据记录.它们使用特殊的语法 ...

  7. zabbix--钉钉告警

    zabbix 钉钉告警机制 群机器人是钉钉群的高级扩展功能,群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步.例如:通过聚合GitHub,GitLab等源码管理服务,实现源码更新同步: ...

  8. ThinkCMF_X1.6.0-X2.2.3框架任意内容包含漏洞的简单分析复现(附自动化验证脚本)

    1.漏洞概述 攻击者可利用此漏洞构造恶意的url,向服务器写入任意内容的文件,达到远程代码执行的目的 2.影响版本 ThinkCMF X1.6.0 ThinkCMF X2.1.0 ThinkCMF X ...

  9. Jmeter中while循环逻辑控制器+配置元件计数器的用法

    一.在线程组下添加逻辑控制器While Controller 二.在逻辑控制器While Controller下添加Sample,BeanShell Sampler , 三.逻辑控制器While Co ...

  10. c# 调用 C++ dll 传入传出类型对应说明(转)

    由于经常使用C#调用 非托管C++ dll 操作一下硬件,出现传入传出类型的问题,现整理了C++ dll 类型与 C#类型对应关系: //C++中的DLL函数原型为        //extern & ...