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你常用的不一定是最快的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)