目录
1、Map介绍
Map是地图键值对构建的数据模型,即Map<key,value>,地图的键key不能重复且只能有一个null,地图的值value可以重复可以为null。
2、Map数据结构及扩容
Map数据结构:数组和链表组合而成;
2.1、数组:寻址容易,插入和删除元素困难
数组由于是紧凑连续存储,可以随机访问,通过索引快速找到对应元素,而且相对节约存储空间。但正因为连续存储,内存空间必须一次性分配够,所以说数组如果要扩容,需要重新分配一块更大的空间,再把数据全部复制过去
2.2、链表:寻址困难,插入和删除元素容易
链表因为元素不连续,而是靠指针指向下一个元素的位置,所以不存在数组的扩容问题;如果知道某一元素的前驱和后驱,操作指针即可删除该元素或者插入新元素。但是正因为存储空间不连续,你无法根据一个索引算出对应元素的地址,所以不能随机访问;而且由于每个元素必须存储指向前后元素位置的指针,会消耗相对更多的储存空间。
2.3、Map数组长度默认16,扩容负载因子为0.75
如果数组长度大于64,并且链表长度大于8,则链表会进化成红黑树;
JDK1.7扩容时,会伴随一次重新的hash分配,并且会遍历Hash表中的所有元素,是非常耗时的。
JDK1.8扩容时,因为每次扩容都是翻倍,与原来计算的(n-1)&hash的结果相比,只是多了一个bit位。
3、Map遍历4种方式及其效率
初始化Map数据,2万条
private static Map<Integer,Integer> map = new HashMap<>();
static {
for (int i = 0; i < 20000; i++){
map.put(i,i * 2);
}
}
3.1、方式一:通过迭代器Iterator遍历
public void test1(){
Long startTime = System.currentTimeMillis();
Iterator<Map.Entry<Integer,Integer>> it = map.entrySet().iterator();
while (it.hasNext()){
Map.Entry<Integer,Integer> entry=it.next();
Integer key = entry.getKey();
Integer value = entry.getValue();
}
long endTime = System.currentTimeMillis();
System.out.println("iterator遍历花费时间为:"+(endTime-startTime));
}
console:iterator遍历花费时间为:4ms
3.2、方式二:通过遍历keySet
public void test2(){
Long startTime = System.currentTimeMillis();
for (Integer key:map.keySet()){
Integer value=map.get(key);
}
long endTime = System.currentTimeMillis();
System.out.println("keySet遍历花费时间为:"+(endTime-startTime));
}
console:keySet遍历花费时间为:4ms
3.3、方式三:通过foreach遍历entry
public void test3(){
Long startTime=System.currentTimeMillis();
for (Map.Entry<Integer,Integer> entry:map.entrySet()){
Integer key = entry.getKey();
Integer value = entry.getValue();
}
long endTime = System.currentTimeMillis();
System.out.println("foreach花费时间为:"+(endTime-startTime));
}
console:foreach花费时间为:3ms
3.4、方式四:通过map.forEach
public void test4(){
Long startTime = System.currentTimeMillis();
map.forEach((key,value) -> {
Integer key1 = key;
Integer value1 = value;
});
long endTime = System.currentTimeMillis();
System.out.println("转换为流遍历花费时间为:"+(endTime-startTime));
}
console:流遍历花费时间为:47ms