• Map.Entry理解和应用


    概述

    Map.Entry是Map接口的一个内部接口,用于获取Map元素的键值对。可以通过map.entrySet()的返回值是一个Set,其类型为Map.Entry,常用的有以下几个方法:

    • getKey():获取元素的键
    • getValue():获取元素的值
    • setValue():设置元素的值

    实例

    Map类型数据的遍历方式

    package com.linfanchen.springboot.lab.map;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class MapEntryTest {
    
        @Test
        public void carPriceTest() {
            Map<String, Integer> carPriceMap = new HashMap<>();
            carPriceMap.put("bmw", 500000);
            carPriceMap.put("benz", 550000);
            carPriceMap.put("lexus", 440000);
    
            // 遍历方式一:使用Map.keySet()
            for (String key : carPriceMap.keySet()) {
                System.out.println("key=" + key + ", value=" + carPriceMap.get(key));
            }
    
            // 遍历方式二(推荐):使用Map.entrySet()的iterator()迭代器
            Iterator<Map.Entry<String, Integer>> iterator = carPriceMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Integer> entry = iterator.next();
                System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
            }
    
            // 遍历方式三(推荐):entrySet()
            for (Map.Entry<String, Integer> entry : carPriceMap.entrySet()) {
                System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
            }
    
            // 遍历方式四:使用map.values()只能获取值
            for (Integer val : carPriceMap.values()) {
                System.out.println("value=" + val);
            }
    
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    遍历效率

    代码

    写个Case验证一下:

    package com.linfanchen.springboot.lab.map;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.*;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class MapEntryTest {
    
        @Test
        public void carPriceTest() {
            Map<String, Integer> carPriceMap = new HashMap<>();
            carPriceMap.put("bmw", 500000);
            carPriceMap.put("benz", 550000);
            carPriceMap.put("lexus", 440000);
    
            // 遍历方式一:使用Map.keySet()
            for (String key : carPriceMap.keySet()) {
                System.out.println("key=" + key + ", value=" + carPriceMap.get(key));
            }
    
            // 遍历方式二(推荐):使用Map.entrySet()的iterator()迭代器
            Iterator<Map.Entry<String, Integer>> iterator = carPriceMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Integer> entry = iterator.next();
                System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
            }
    
            // 遍历方式三(推荐):entrySet()
            for (Map.Entry<String, Integer> entry : carPriceMap.entrySet()) {
                System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
            }
    
            // 遍历方式四:使用map.values()只能获取值
            for (Integer val : carPriceMap.values()) {
                System.out.println("value=" + val);
            }
    
    
    
        }
    
        @Test
        public void speedTest() {
            {
                // 构造500w的数据源
                HashMap<Integer, String> hashmap = new HashMap<Integer, String>();
                for (int i = 0; i < 5000000; i++) {
                    hashmap.put(i, "lfc");
                }
    
                long bs = Calendar.getInstance().getTimeInMillis();
                Iterator iterator = hashmap.keySet().iterator();
                while (iterator.hasNext()) {
                    hashmap.get(iterator.next());
                }
                System.out.print("keyset:");
                System.out.println(Calendar.getInstance().getTimeInMillis() - bs);
    
            }
    
            {
                // 构造500w的数据源
                HashMap<Integer,String> hashmap = new HashMap<Integer,String>();
                for (int i = 0; i < 5000000; i++ ) {
                    hashmap.put(i, "lfc");
                }
                long bs = Calendar.getInstance().getTimeInMillis();
                Iterator it = hashmap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry entry = (Map.Entry) it.next();
                    entry.getValue();
                }
                System.out.print("entryset:");
                System.out.println(Calendar.getInstance().getTimeInMillis() - bs);
            }
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    输出:

    keyset:120
    entryset:98
    
    • 1
    • 2

    从输出结果看出entryset的方式便利性能会好很多,那为什么呢?
    从源码找答案:

    public V get(Object key) {
            if (key == null)
                return getForNullKey();
            Entry<K,V> entry = getEntry(key);
     
            return null == entry ? null : entry.getValue();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • hashmap.entryset:在set集合中存放的是entry对象。而在hashmap中的key 和 value 是存放在entry对象里面的;然后用迭代器,遍历set集合,就可以拿到每一个entry对象;得到entry对象就可以直接从entry拿到value了;
    • hashmap.keyset:只是把hashmap中key放到一个set集合中去,还是通过迭代器去遍历,然后再通过 hashmap.get(key)方法拿到value;

    源码

    位于 java.util.Map

    public interface Entry<K, V> {
    		/*
    		* 获取键
    		*/
            K getKey();
    
    		/*
    		* 获取值
    		*/
            V getValue();
    
    		/*
    		* 设置值
    		*/
            V setValue(V var1);
    
            boolean equals(Object var1);
    
            int hashCode();
    
    		/*
    		* 根据键比较,具体比较的逻辑
    		*/
            static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
                return (Comparator)((Serializable)((c1, c2) -> {
                    return ((Comparable)c1.getKey()).compareTo(c2.getKey());
                }));
            }
    
    		/*
    		* 根据值比较,具体比较的逻辑
    		*/
            static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
                return (Comparator)((Serializable)((c1, c2) -> {
                    return ((Comparable)c1.getValue()).compareTo(c2.getValue());
                }));
            }
    
    		/*
    		* 根据键比较,具体比较的逻辑
    		*/
            static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
                Objects.requireNonNull(cmp);
                return (Comparator)((Serializable)((c1, c2) -> {
                    return cmp.compare(c1.getKey(), c2.getKey());
                }));
            }
    
    		/*
    		* 根据值比较,具体比较的逻辑
    		*/
            static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
                Objects.requireNonNull(cmp);
                return (Comparator)((Serializable)((c1, c2) -> {
                    return cmp.compare(c1.getValue(), c2.getValue());
                }));
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    总结

    在日常的开发中,要注意map类型的遍历效率。可以使用entrySet()高效遍历,节省程序的运行时间。PS:苹果系统为什么能那么流畅,就是尽量优化每一行代码的效率,我们也要遵循一样的理念。

  • 相关阅读:
    Linux查看文件的命令 file head tail cat more less
    Vue3开始
    力扣283题:移动零
    推荐一款可以下载B站视频和音频的工具
    JavaScript之语法专题(类型转换,报错分析等)
    LeetCode //C - 162. Find Peak Element
    JUC并发编程第二篇,对Future的改进,CompletableFuture核心使用
    STM32 寄存器配置笔记——系统时钟配置 HSE as PLL
    程序环境和预处理
    大数据开发面试(一)
  • 原文地址:https://blog.csdn.net/oschina_41731918/article/details/126078735