北京电脑培训分享Map的存储方式解析

北京电脑培训分享Map的存储方式解析,第1张

HashCode()的作用是为每一个引用类型的元素分配一个唯一的哈希码,北京电脑培训发现这个哈希码就像对象的引用地址一样,在内存中不会重复,是一个唯一值。

在Map元素存储时,将哈希码通过计算,生成一个在数组长度范围内的数,这里我用 index代替解释,然后将index设定为Map元素在数组中的下标,将Map元素存储在所对应的index位置上,这样在进行查找Map元素时就可以通过该Map元素的哈希码对数组长度取余数即可直接在数组中找到对应的Map元素。

这里我先对获得index的计算方式进行介绍,我们知道,数组有固定的长度,那么只要我们将哈希码对数组长度取余数,那么这个余数一定是在数组长度范围内的,也就是在0-数组长度减一的范围内,这样正好是数组下表的范围。

即:哈希码%数组长度 =  [0, 数组长度-1]

当然,这里有一点需要注意,不同的哈希码对数组长度取余数之后,可能得到相同的余数,在这里,链表就派上了用场。

采用这样的存储结构,在查找Map元素时,只需要通过分配给每一个元素的哈希码%数组长度,即可得到该Map元素在数组中的索引值,然后通过索引值找到Map元素在数组中的位置,如果改位置链表存在多个元素,只需对该位置的链表进行便利查找即可找到对应的Map元素值,极大地提高了查找效率。上海尚学堂java培训信恒涛原创,转载请说明出处。

1、遍历MapentrySet():它的每一个元素都是MapEntry对象,这个对象中,

放着的就是Map中的某一对key-value;

2、遍历MapkeySet():它是Map中key值的集合,我们可以通过遍历这个集合来

读取Map中的元素;

3、遍历Mapvalues():它是Map中value的集合,我们可以直接通过这个集合遍历

Map中的值,却不能读取key。

如文章标题所言,遍历Map是开发过程中比较常见的行为,实现的方式也有多种方式,本文带领大家一起看看更加高效的遍历 Map 。

首先一起来看看,有哪些遍历 Map 的方式

这种应该算是比较常见的使用方式,也是比较容易理解的

keySet : 获取 map 中所有的 key ,然后依次遍历每个 key 。

这种是我平时开发中用的最多的方式,简单通俗易懂。

但是其性能如何呢?后续待揭秘。

不知道有多少人用过 Java8 中的 parallel模式,本质是一种并行处理方式。

性能如何?稍后揭晓。

不行就找找外援试试?

测试环境如下:Intel i7-4790 360 GHz, 16 GB

测试集为小的Map集合(大约100个元素),各个方法耗时如下:

从结果看出,在数据量比较小时, 利用 Java 8中的foreach 暂时领先。

测试集为元素数据量 1000 的 Map 集合,测试结果如下:

从结果集合看,在中等数据量情况下,外援 Eclipse (CS) collections 中的 MutableMap 表现最为优异,勇得第一。

其次为 Java 8 中的 foreach ,位列第二。

测试集为元素数据量 100000 (十万级别) 的 Map 集合,测试结果如下:

利用 iterator 和 MapEntry 方法1稳居第一,领先 第二名差不多7s。

第二名为 Eclipse (CS) collections 中的 MutableMap 位列第二,在大数据量下表现表现比较出色。

指的注意的是之前在小数据量下表现比较出色的 Java 8 中的 foreach ,排名却比较靠后,但是仍然超过了利用 Java8 的 Stream API 。

其中还有另一个现象:利用并行模式计算的 Java8 中的 Stream API parallel ,在大数据量时表现好于 foreach 和 stream api 。

下表为不同数据量情况下的各个方法性能表现

在平时开发中,数据量都不算太大时,剖除外援而言, Java 8 中的 foreach 方法3,表现比较优异。而并行运算的 Stream API parallel 方法8表现没有想象中好, Stream API 方法7表现中规中矩。

主要罗列了多种遍历 Map 的方式,每个实现方式都有各自的特点,有的人喜欢 foreach 的通俗易懂;有的人喜欢 stream 的干净利落。

如果从性能来看,小数据量情况下:优先推荐使用 Java8 Foreach 方法3。

大数据量情况下推荐 使用 iterator 和 MapEntry 方法1。

我是大黄,一个只会写 HelloWorld 的程序员,下期见。

map是一种映射,是常用的STL容器。(map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器))

如需使用,需要加一个map头文件。

1map的定义:

map mp;

使用map要确定映射前类型(键key)和映射后的类型(值value)。

注意:如果是字符串到整形的映射,必须使用string而不是char数组。

例子:

(1)map<set ,string>mp;</set

2map容器内元素的访问:

(1)通过下标访问:

比如:

map mp;

mp['c']=20;

mp['c']=30;

printf("%d",m['c'])输出的是30;

(2)通过迭代器访问:

定义方式:

map ::iterator it;

map迭代器的使用方式和其他STL容器的迭代器不同,因为map的每一对映射都有两个typename,这决定了必须能通过一个it来同时访问键和值。事实上,map可以使用it->first来访问键,使用it->second来访问值。

3map常用函数实例解析:

(1)find()

find(key)返回键为key的映射的迭代器,时间复杂度为N(logN),N为map中映射的个数。

(2)erase()

erase有两种用法:

第一种:删除单个元素,删除一个区间内的所有元素。

删除单个元素的方法==》mperase(it),it为删除的元素的迭代器,时间复杂度为O(1)。

mperase(key),key为欲删除的键。时间复杂度为O(logN),N为map内元素的个数。

第二种:删除一个区间内的所有元素。

mperase(firse,last)删除[first,last)

时间复杂度O(last-first)

(3)size()

size()用来获得map中映射的对数,时间复杂度为O(1)。

(4)clear()

clear()用来清空map中的所有元素,复杂度为O(N),其中N为map中的元素的个数。

4map的常见用途:

1需要建立字符(或字符串)与整数之间映射的题目,使用map可以减少代码量。

2判断大整数或者其他类型数据是否存在的题目,可以把map当bool数组用。

3字符串和字符串的映射有时候也会遇到!

java 获取map中所有的key和value值

javautilIterator 对 collection 进行迭代的迭代器。

javautilIterator it = mapentrySet()iterator();

while(ithasNext()){

javautilMapEntry entry = (javautilMapEntry)itnext();

entrygetKey() //返回对应的键

entrygetValue() //返回对应的值

}

以前遍历Map key-value比较习惯的方式是先获取Map中的所有key值,

然后根据key,依次从Map中去数据,基本方式如下:

Map<String,String> testData = new HashMap<String, String>();

Set<String> keys = testDatakeySet();

for(String key :keys){

Systemoutprintln(key+" "+testDataget(key));

}

上述其中是第一种方法,原来一直用上述方法主要是自己有点懒,有了一种方法后就觉得够用的了,今天看源码,发现还Map接口中还有一个Entry<K,V>的接口,对应的还有一个 Set<MapEntry<K, V>> entrySet();方法。

也就是说其实Map中的每条key-value数据对应着一个Entry,这样的话遍历Map其实就是要取出每个Entry,也就有了第二种遍历方法:

Set<Entry<String, String>> entries = testDataentrySet();

for (Entry<String, String> entry : entries) {

Systemoutprintln(entrygetKey()+":"+entrygetValue());

}

当少量的数据时,上述两种方法的效率是差不多的,当数据比较多时,第二种还是要比第一种快。

当然上述说的两种遍历针对的情况是遍历出key-value,如果是只想遍历key或value,大可不必用以上的方法了,Map中提供了Set<K> keySet()和Collection<V> values()。

第一个,使用keySet方法,获得key的set,然后遍历set,就可以获得所有的value 第二个,使用entrySet方法,获得map中的所有键值对的一个视图,遍历就可获得所有的key、value

map容器的迭代器里面有first ()和 second(),second是值,用来返回数据。

例如:

map<string, int> m;

m["one"] = 1;

map<string, int>::iterator p = mbegin();

p->first; // 这个是  string  值是 "one"

p->second; //这个是 int 值是 1

std::map<X, Y>实际储存了一串std::pair<const X, Y>,std::map<std::string, int> m = / fill it /;、auto it = mbegin();

这里,如果你用it,那么你将得到map第一个元素的std::pair,现在你可以接收std::pair的两个元素:,(it)first会得到key,(it)second会得到value,这等同于it->first和it->second。

扩展资料:

Iterator在Collection接口中的使用。

虽然Collection接口的相关类实现了get()方法,但将Iterator用在它们身上仍然是合适的,下面以ArrayList为例,讨论Iterator在Collection中的两中使用方法

1、配合while()循环实现遍历输出:

ArrayList list = new ArrayList();

Iterator it = listiterator();

while(ithasNext()){

Systemoutprintln(itnext());6}

while()中的判断条件ithasNext()用于判断it中是否还有下一元素,有的话就继续循环,输出语句中的itnext()既可以使“指针”往后走一位,又能将当前的元素返回,用于输出。

2、配合for()循环实现遍历输出:

ArrayList list = new ArrayList();

for(Iterator it = listiterator();ithasNext();){

Systemoutprintln(itnext()); }

以上就是关于北京电脑培训分享Map的存储方式解析全部的内容,包括:北京电脑培训分享Map的存储方式解析、怎么写一个es6的map遍历方法、如何高效的遍历Map你常用的不一定是最快的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9545324.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存