Map遍历四种方式及其效率

目录

1、Map介绍

2、Map数据结构及扩容

2.1、数组:寻址容易,插入和删除元素困难

2.2、链表:寻址困难,插入和删除元素容易

2.3、Map数组长度默认16,扩容负载因子为0.75

3、Map遍历4种方式及其效率

3.1、方式一:通过迭代器Iterator遍历

3.2、方式二:通过遍历keySet

3.3、方式三:通过foreach遍历entry

3.4、方式四:通过map.forEach


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

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值