• 80-Java的Map集合:概述、API、遍历方式


    Map集合体系

    一、Map集合的概述

    1、概述和使用
    • Map集合是一种双列集合,每个元素包含两个数据。
    • Map集合的每个元素的格式:key=value(键值对元素)。
    • Map集合也称为“键值对集合”。

    2、格式:
    • Collection集合的格式:

      [元素1, 元素2, 元素3, ...]
      
      • 1
    • Map集合的格式:

      {key1=value1, key2=value2, key3=value3, ...}
      
      • 1
    • 通俗点讲就是,key是老公,value是老婆,都是成双成对的,并且不能出轨。
      在这里插入图片描述


    3、使用场景之一:购物车系统

    在这里插入图片描述


    分析:

    • 购物车购买提供的四个商品和购买数量在后台需要容器存储。

    • 每个商品对象都一一对应一个购买数量。

    • 把商品对象看成是Map集合的键,购买数量看成Map集合的值。

      {商品1=2, 商品2=3, 商品3=2, 商品4=3}
      
      • 1

    总结

    1、Map集合是什么?适用场景是什么样的?

    • Map集合是键值对集合
    • Map集合非常适合做类似购物车这样的业务场景



    二、Map集合体系特点

    在这里插入图片描述


    1、说明
    • 使用最多的Map集合是HashMap
    • 重点掌握HashMap,LinkedHashMap,TreeMap。其他的后续讲解。

    2、Map集合体系特点
    • Map集合的特点都是由键决定的
    • Map集合的键是无序、不重复、无索引,值不做要求
    • Map集合后面重复的键对应的值会覆盖前面重复键的值
    • Map集合的键值对都可以为null

    在这里插入图片描述


    3、Map集合实现类特点
    • HashMap:元素按照键是无序、不重复、无索引,值不做要求。(与Map(父亲)体系一致)

      在这里插入图片描述



    • LinkedHashMap:元素按照键是有序、不重复、无索引,值不做要求

      在这里插入图片描述



    • TreeMap:元素按照键是排序、不重复、无索引,值不做要求

    总结

    1、Map集合的特点是什么样的?

    • HashMap:元素按照键是无序、不重复、无索引,值不做要求。
    • LinkedHashMap:元素按照键是有序、不重复、无索引,值不做要求。
    • TreeMap:元素按照键是排序、不重复、无索引,值不做要求。



    三、Map集合常用API

    1、Map集合
    • Map是双列集合的祖宗接口,它的功能是全部双列集合都可以继承使用的。

    Map的API如下

    方法说明
    V put(K key, V value)添加元素
    V remove(Object key)根据键删除键值对元素
    V get(Object key)根据键获取对应的值
    Set< K > keyset()获取全部键的集合
    Collection< V > values()获取全部值的集合
    void clear()移除所有键值对元素
    boolean containsKey(Object key)判断集合是否包含指定的键
    boolean containsValue(Object value)判断集合是否包含指定的值
    boolean isEmpty()判断集合是否为空
    int size()集合的长度,也就是集合中键值对的个数
    void putAll(Map m)把一个集合中的所有元素拷贝到另一个集合中去

    package com.app.d8_map_api;
    
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
        目标:掌握Map集合体系的常用API
     */
    public class MapAPIDemo1 {
        public static void main(String[] args) {
    //        1、添加元素:无序、不重复、无索引。
            Map<String, Integer> maps = new HashMap<>();
            maps.put("李宁音速6", 10);
            maps.put("娃娃", 20);
            maps.put("李宁音速6", 100); // Map集合后面的键对应的元素,会覆盖前面重复的整个键值对元素。
            maps.put("华为nova7", 100);
            maps.put("毛巾", 10);
            maps.put("手表", 10);
    
            System.out.println(maps);   // {手表=10, 李宁音速6=100, 华为nova7=100, 娃娃=20, 毛巾=10}
    
    //        2、清空集合
            // maps.clear();
            // System.out.println(maps);
    
            System.out.println("-----------------------------------");
    //        3、判断集合是否为空,为空返回true,反之!
            System.out.println(maps.isEmpty());
    
            System.out.println("-----------------------------------");
    //        4、根据键获取对应值
            Integer key = maps.get("李宁音速6");
            System.out.println(key);  // 100
            System.out.println(maps.get("华为nova7"));    // 100
            System.out.println(maps.get("华为nova9"));    // null
    
            System.out.println("-----------------------------------");
    //        5、根据键删除整个元素。(删除键会返回键的值)
            System.out.println(maps.remove("娃娃"));
            System.out.println(maps);
    
            System.out.println("-----------------------------------");
    //        6、判断是否包含某个键,包含返回true,反之!
            System.out.println(maps.containsKey("华为nova7"));    // true
            System.out.println(maps.containsKey("娃娃"));         // false
            System.out.println(maps.containsKey("娃娃2"));       // false
    
            System.out.println("-----------------------------------");
    //        7、判断是否包含某个值,包含返回true,反之!
            System.out.println(maps.containsValue(100));    // true
            System.out.println(maps.containsValue(10));     // false
            System.out.println(maps.containsValue(33));     // false
    
            System.out.println("-----------------------------------");
            // {手表=10, 李宁音速6=100, 华为nova7=100, 娃娃=20, 毛巾=10}
    //        8、获取全部键的集合:Set keySet()
            // 为什么用Set集合来接?因为Set集合:无序、不重复、无索引,符合Map集合的键的特点
            Set<String> keys = maps.keySet();
            System.out.println(keys);   // [李宁音速6, 华为nova7, 娃娃, 毛巾]
    
            System.out.println("-----------------------------------");
    //        9、获取全部值的集合:Collection values()
            // 为什么用Collection集合来接?因为Collection集合:可重复,可以保留重复的值
            Collection<Integer> values = maps.values();
            System.out.println(values);     // [10, 100, 100, 10]
    
            System.out.println("-----------------------------------");
    //        10、集合的大小
            System.out.println(maps.size());    // 4,因为键值对是一个整体
    
            System.out.println("----------------拓展---------------");
    //        11、合并其他Map集合。(拓展)
            Map<String, Integer> map1 = new HashMap<>();
            map1.put("java1", 1);
            map1.put("java2", 100);
    
            Map<String, Integer> map2 = new HashMap<>();
            map2.put("java2", 1);
            map2.put("java3", 100);
    
            map1.putAll(map2);  // 把集合map2的元素拷贝一份到map1中去
            System.out.println(map1);
            System.out.println(map2);
        }
    }
    
    • 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
    • 86
    • 87
    {手表=10, 李宁音速6=100, 华为nova7=100, 娃娃=20, 毛巾=10}
    -----------------------------------
    false
    -----------------------------------
    100
    100
    null
    -----------------------------------
    20
    {手表=10, 李宁音速6=100, 华为nova7=100, 毛巾=10}
    -----------------------------------
    true
    false
    false
    -----------------------------------
    true
    true
    false
    -----------------------------------
    [手表, 李宁音速6, 华为nova7, 毛巾]
    -----------------------------------
    [10, 100, 100, 10]
    -----------------------------------
    4
    ----------------拓展---------------
    {java3=100, java2=1, java1=1}
    {java3=100, java2=1}
    
    Process finished with exit code 0
    
    • 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



    四、Map集合的遍历方式一:键找值

    • 键找值的方式遍历:先获取Map集合全部的键,再根据遍历键找值。
    1、键找值流程
    • 取出全部键的集合后,遍历键的Set集合,然后根据键找对应的值。

      在这里插入图片描述


    2、键找值涉及的API
    方法说明
    Set< K > keySet()获取所有键的集合
    V get(Object key)根据键获取值

    package com.app.d9_map_traverse;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
        目标:掌握Map集合的遍历方式一:键找值
     */
    public class MapTraverseDemo1 {
        public static void main(String[] args) {
    //         创建一个Map集合,添加一些数据
            Map<String, Integer> maps = new HashMap<>();
            maps.put("宇智波鼬手办", 20);
            maps.put("Nike跑鞋", 100);
            maps.put("手表", 20);
            maps.put("U盘", 2000);
            System.out.println("遍历前:" + maps);  // {手表=20, 宇智波鼬手办=20, U盘=2000, Nike跑鞋=100}
    
            System.out.println();
    
    //        键找值遍历方式
            // 1、先获取全部键的集合
            Set<String> keys = maps.keySet();
    
            // 2、遍历全部的键
            System.out.println("遍历后:");
            for (String key : keys) {
                // 根据键得到对应的值
                int value = maps.get(key);
                System.out.println(key + "==>" + value);
            }
        }
    }
    
    • 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
    遍历前:{手表=20, 宇智波鼬手办=20, U盘=2000, Nike跑鞋=100}
    
    遍历后:
    手表==>20
    宇智波鼬手办==>20
    U盘==>2000
    Nike跑鞋==>100
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9



    五、Map集合的遍历方式二:键值对

    • 键值对的方式遍历:把 “键值对” 看成一个整体,难度较大。
    1、键值对流程
    • 先把Map集合转换成Set集合,Set集合中的每个元素都是键值对实体类型了。
    • 然后再遍历Set集合,提取出键以及值。

    在这里插入图片描述


    2、键值对涉及的API
    方法说明
    Set< Map.Entry< K, V > > entrySet()获取所有键值对对象的集合
    K getKey()获取键
    V getValue()获取值

    package com.app.d9_map_traverse;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
        目标:掌握Map集合的遍历方式二:键值对
     */
    public class MapTraverseDemo2 {
        public static void main(String[] args) {
    //        创建一个Map集合,添加一些数据
            Map<String, Integer> maps = new HashMap<>();
            maps.put("宇智波鼬手办", 20);
            maps.put("Nike跑鞋", 100);
            maps.put("手表", 20);
            maps.put("U盘", 2000);
            System.out.println("遍历前:" + maps);  // {手表=20, 宇智波鼬手办=20, U盘=2000, Nike跑鞋=100}
    
            System.out.println();
    
            /*
                {手表=20, 宇智波鼬手办=20, U盘=2000, Nike跑鞋=100}
                    ☟
                使用foreach遍历Map集合,发现Map集合的键值对元素是没有直接类型的,因此不能直接foreach遍历集合。
                    ☟
                通过调用Map集合的API,entrySet()方法把Map集合转换成Set集合形式:maps.entrySet()。
                方法内部其实也是先将全部键和全部值遍历出来,然后将键和值封装成一个对象,这样就可以作为一个对象遍历了
                [(手表=20), (宇智波鼬手办=20), (U盘=2000), (Nike跑鞋=100)]
                                entry
                    ☟
                Set> entries = maps.entrySet();
                    ☟
                此时可以使用foreach遍历这个键值对对象了
             */
            // 1、把Map集合转换成Set集合形式:将键值对封装成一个对象
            Set<Map.Entry<String, Integer>> entries = maps.entrySet();
    
            // 2、使用foreach遍历这个键值对对象
            System.out.println("遍历后:");
            for (Map.Entry<String, Integer> entry : entries){
                String key = entry.getKey();    // 获取键
                int value = entry.getValue();   // 获取值
                System.out.println(key + "==>" + value);
            }
        }
    }
    
    • 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
    遍历前:{手表=20, 宇智波鼬手办=20, U盘=2000, Nike跑鞋=100}
    
    遍历后:
    手表==>20
    宇智波鼬手办==>20
    U盘==>2000
    Nike跑鞋==>100
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9



    六、Map集合的遍历方式三:Lambda表达式

    • lambda表达式遍历:JDK8开始后的新技术。
    • 得益于JDK8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式。

    1、Map结合Lambda遍历的API
    方法说明
    default void forEach(BiConsumer action)结合lambda遍历Map集合

    2、流程

    在这里插入图片描述


    package com.app.d9_map_traverse;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.function.BiConsumer;
    
    /**
        目标:掌握Map集合的遍历方式三:结合lambda表达式遍历Map集合
     */
    public class MapTraverseDemo3 {
        public static void main(String[] args) {
    //        创建一个Map集合,添加一些数据
            Map<String, Integer> maps = new HashMap<>();
            maps.put("宇智波鼬手办", 20);
            maps.put("Nike跑鞋", 100);
            maps.put("手表", 20);
            maps.put("U盘", 2000);
            System.out.println("遍历前:" + maps);  // {手表=20, 宇智波鼬手办=20, U盘=2000, Nike跑鞋=100}
    
            System.out.println();
    
    //        1、使用JDK8后的新技术,结合lambda遍历map
            // {手表=20, 宇智波鼬手办=20, U盘=2000, Nike跑鞋=100}
            /*
                分析:
                 其实forEach()内部是用方式二帮我们遍历的:
                    先将Map集合转换成Set集合形式:将键值对封装成一个对象;
                    取出键和值,回调accept()方法,分别将键和值传送给这里
             */
            /*maps.forEach(new BiConsumer() {
                @Override
                public void accept(String key, Integer value) {
                    System.out.println(key + "==>" + value);
                }
            });*/
    
            System.out.println("遍历后:");
            maps.forEach(( k, v) -> System.out.println(k + "==>" + v) );
        }
    }
    
    • 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
    遍历前:{手表=20, 宇智波鼬手办=20, U盘=2000, Nike跑鞋=100}
    
    遍历后:
    手表==>20
    宇智波鼬手办==>20
    U盘==>2000
    Nike跑鞋==>100
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、分析

    在这里插入图片描述




    七、Map集合案例:统计投票人数

    1、需求:
    • 某个班级80名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A、B、C、D),每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。
    2、分析:
    • 将80个学生选择的景点拿到程序中。
    • 定义Map集合用于存储最终统计的结果。
    • 遍历80个学生选择的景点,看Map集合中是否存在,不存在存入 “某景点=1”,存在则其对应值+1。
    • 统计完选择票数后,优化输出。

    3、实现:
    package com.app.d10_map_test;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Random;
    
    /**
        需求:
            某个班级80名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A、B、C、D),
            每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。
     */
    public class MapTest {
        public static void main(String[] args) {
    //       1、将80个学生选择的景点拿到程序中。
            // a、提供四个景点给学生选择:A B C D(个数确定、类型确定。数组存)
            String[] selects = {"A", "B", "C", "D"};
    
            // b、创建随机数对象,用于随机一个索引,模拟学生选择景点
            Random rd = new Random();
    
            // c、创建StringBuilder对象,用于拼接80名学生的选择结果
            StringBuilder sb = new StringBuilder();
    
            // d、模拟80名学生选择景点
            for (int i = 0; i < 80; i++) {
                // e、拼接80名学生选择的结果
                sb.append(selects[rd.nextInt(selects.length)]);
            }
    
            System.out.println("随机选择结果:" + sb);     // 80名学生的最终选择结果
            
    
    //       2、定义Map集合用于存储最终统计的结果。例如:选择A景点=30名学生,B=20,C=20,D=10。键是景点,值是选择数量
            Map<Character, Integer> infos = new HashMap<>();
            
    
    //       3、遍历80个学生选择的景点,看Map集合中是否存在,不存在存入 “某景点=1”,存在则其对应值+1。
            // a、定义循环遍历80名学生选择的景点
            for (int i = 0; i < sb.length(); i++) {
                // b、提取当前选择的景点字符
                char attraction = sb.charAt(i);
    
                // c、判断当前选择的景点是否存在于集合中
                if (infos.containsKey(attraction)){
                    // 存在,说明此景点不是第一次被选择,让其景点的选择票数+1
                    infos.put(attraction, infos.get(attraction) + 1);
                }else {
                    // 不存在,说明此景点是第一次被选择,让其景点的选择票数为1
                    infos.put(attraction, 1);
                }
            }
    
            // System.out.println("最终统计票数:" + infos);
            
    
            // 4、统计完选择票数后,优化输出
            infos.forEach( (k, v) -> System.out.println("景点" + k + "的选择票数:" + v) );
        }
    }
    
    • 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
    随机选择结果:CBCCADAACCAABCDCCBBACBDBDDDDBBDABCDAACBDDABCDDDDABDDDAABCCCDABCCBBCABDDBDAABADBC
    景点A的选择票数:18
    景点B的选择票数:20
    景点C的选择票数:19
    景点D的选择票数:23
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7


    4、Debug分析执行流程:

    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    • 只需要自己控制程序一步一步往下走,就可以看完整个执行流程了!!

    • 如果已经明白了整个流程,不想看了,可以结束Debug的执行:

      在这里插入图片描述


      在这里插入图片描述





    八、Map集合的实现类HashMap

    1、特点
    • HashMap是Map接口里面的一个实现类。
    • 特点是由键决定的:无序、不重复、无索引。
    • 没有额外需要学习的特有API,直接使用Map里面的API方法就可以了。

    2、原理
    • HashMap跟HashSet底层原理是一模一样的,都是哈希表结构,只是HashMap的每个元素包含两个值(键值对)而已。

    • 实际上:Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。

      在这里插入图片描述



    • HashMap的添加原理:

      • 将键、值作为一个Entry对象,然后获取Entry对象的哈希值,对底层位置求余,存入求余结果对应的位置。
        在这里插入图片描述


        在这里插入图片描述



      • 如果下一个要添加的元素也算到了同一个位置,就会形成链表,当链表长度超过8,就会自动转换为红黑树。
        在这里插入图片描述


        在这里插入图片描述




    总结

    1、HashMap的特点和底层原理是什么样的?

    • 由键决定:无序、不重复、无索引。

    • HashMap底层是哈希表结构的。

    • 依赖hashCode和equals方法保证的唯一。

    • 如果要存储的是自定义对象,需要重写hashCode和equals方法。

      在这里插入图片描述


      在这里插入图片描述



    • 基于哈希表。增删改查的性能都较好。



    九、Map集合的实现类LinkedHashMap

    1、特点
    • 由键决定:有序、不重复、无索引。
    • 这里的有序指的是:保证存储和取出的元素顺序一致。

    2、原理
    • 底层数据结构依然是哈希表,只是每个键值对元素额外多了一个双链表的机制记录存储的顺序。

      • 将要添加的键值对封装成一个对象,然后对底层数组长度求余,存入求余结果对应的位置;

      • 然后上一个元素记住下一个元素的地址,下一个元素又记住上一个元素的地址,形成一个双链表。
        在这里插入图片描述


    3、使用

    在这里插入图片描述




    十、Map集合的实现类TreeMap

    1、特点
    • 由键决定:可排序、不重复、无索引。
    • 可排序:按照键数据的大小默认升序(从小到大)排序。只能对键排序
    • 注意:TreeMap集合是一定要排序的,可以默认排序,也可以将键按照指定的规则进行排序

    2、原理
    • TreeMap跟TreeSet的底层原理是一样的。

    • 实际上:TreeSet底层是基于TreeMap设计的。

      在这里插入图片描述


    3、自定义排序规则有2种
    • 类实现Comparable接口,重写比较规则。
    • 集合自定义Comparator比较器对象,重写比较规则。
    package com.app.d11_map_impl;
    
    /**
        自定义类:猫类。
        指定规则排序方式一:
            让自定义的类实现Comparable接口重写里面的compareTo方法,来自定义比较规则。
     */
    public class Cat implements Comparable<Cat>{
        /**
            猫的属性:昵称、毛色、价格、重量
         */
        private String name;
        private String color;
        private double price;
        private int weight;
        
        
        /**
         * 重写Comparable接口的compareTo方法,来自定义比较规则。
         * @param o 接收一个猫对象
         * @return
         */
        @Override
        public int compareTo(Cat o) {
            // 自定义比较规则:按照猫的重量升序排序
            return this.weight - o.weight;                  // 去除重量重复的数据
            // return this.weight - o.weight >= 0 ? 1 : -1;    // 保留重量重复的数据
        }
        
    
        public Cat(){
    
        }
    
        public Cat(String name, String color, double price, int weight) {
            this.name = name;
            this.color = color;
            this.price = price;
            this.weight = weight;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    
        public int getWeight() {
            return weight;
        }
    
        public void setWeight(int weight) {
            this.weight = weight;
        }
    
        @Override
        public String toString() {
            return "Cat{" +
                    "name='" + name + '\'' +
                    ", color='" + color + '\'' +
                    ", price=" + price +
                    ", weight=" + weight +
                    '}';
        }
    
    
    }
    
    • 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
    package com.app.d11_map_impl;
    
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Map;
    import java.util.TreeMap;
    
    /**
        目标:掌握Map集合的实现类:TreeMap
        特点:可排序、不重复、无索引
     */
    public class TreeMapDemo3 {
        public static void main(String[] args) {
            // 多态写法
            // 1、默认排序
            Map<Integer, String> cats = new TreeMap<>();
            cats.put(13, "小花猫");
            cats.put(2, "小黑猫");
            cats.put(23, "小白猫");
            cats.put(1, "小黄猫");
    
            cats.forEach( (k, v) -> System.out.println(k + " : " + v) );
    
            System.out.println("------------------------------------");
    
    
            // Map students = new TreeMap<>();     // 一行经典代码
    
            // 2、自定义排序规则:
            // 方式二:集合自定义Comparator比较器对象,重写比较规则。
            // 按照猫的价格来降序排序
            Map<Cat, String> students = new TreeMap<>((o1, o2) ->
                Double.compare(o2.getPrice(), o1.getPrice())
            );
    
            students.put(new Cat("胖球", "花白色", 899.9, 40), "广西");
            students.put(new Cat("咪咪", "白色", 666.5, 40), "湖北");
            students.put(new Cat("小黑", "黑色", 899.8, 25), "广州");
            students.put(new Cat("虾皮", "黄色", 566.9, 33), "安徽");
    
            students.forEach( (k, v) -> System.out.println(k + " = " + v) );
        }
    }
    
    • 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
    1 : 小黄猫
    2 : 小黑猫
    13 : 小花猫
    23 : 小白猫
    ------------------------------------
    Cat{name='胖球', color='花白色', price=899.9, weight=40} = 广西
    Cat{name='小黑', color='黑色', price=899.8, weight=25} = 广州
    Cat{name='咪咪', color='白色', price=666.5, weight=40} = 湖北
    Cat{name='虾皮', color='黄色', price=566.9, weight=33} = 安徽
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11



    补充知识:集合的嵌套

    1、案例导学:统计投票人数
    • 需求
      • 某个班级多名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A、B、C、D),每个学生可以选择多个景点,请统计出最终哪个景点想去的人数最多。
    • 分析
      • 将多名学生选择的数据拿到程序中,需要记住每个学生选择的情况。
      • 定义Map集合用于存储最终统计的结果。
    package com.app.d11_map_impl;
    
    import java.util.*;
    
    /**
        目标:通过案例导学,理解集合嵌套
        需求:某个班级多名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A、B、C、D),
             每个学生可以选择多个景点,请统计出最终哪个景点想去的人数最多。
     */
    public class MapTest4 {
        public static void main(String[] args) {
    //        1、模拟多名学生选择景点,记住每个学生选择的情况
            // a、创建一个集合存储学生选择的景点数据
            Map<String, List<String>> data = new HashMap<>();
    
            // b、将学生选择的景点数据存入集合中
            List<String> stuSelects1 = new ArrayList<>();           // 创建一个集合用于存储学生选择的景点数据
            Collections.addAll(stuSelects1, "A", "C");     // 存储学生选择的景点数据
            data.put("张飞", stuSelects1);         // 将学生选择的景点数据存入集合
    
            List<String> stuSelects2 = new ArrayList<>();
            Collections.addAll(stuSelects2, "B", "C", "D");
            data.put("关羽", stuSelects2);
    
            List<String> stuSelects3 = new ArrayList<>();
            Collections.addAll(stuSelects3, "A", "B", "C", "D");
            data.put("赵云", stuSelects3);
    
            System.out.println("所有学生的选择情况:" + data);
            // 所有学生的选择情况:{关羽=[B, C, D], 张飞=[A, C], 赵云=[A, B, C, D]}
            //                        values
    
    //        2、统计多名学生的最终投票人数
            // a、创建集合用于统计每个景点的投票人数
            Map<String, Integer> infos = new HashMap<>();
    
            // b、得到所有人选择的景点数据(值)
            Collection<List<String>> values = data.values();
            //System.out.println("所有人选择的景点数据:" + values);
            // 所有人选择的景点数据:[[B, C, D], [A, C], [A, B, C, D]]
            //                      value
    
            // c、循环遍历所有人选择的景点数据
            for (List<String> value : values) {
                // [B, C, D]
                //  a
                // d、循环遍历单个人选择的景点数据
                for (String a : value) {
                    // e、判断此景点是否存在于集合中
                    if (infos.containsKey(a)) {
                        // 存在,说明此景点不是第一次被选择,让其选择数量+1
                        infos.put(a, infos.get(a) + 1);
                    }else {
                        // 不存在,说明此景点是第一次被选择,让其选择数量为1
                        infos.put(a, 1);
                    }
                }
            }
    
    //        3、统计完每个景点的投票人数,优化输出
            infos.forEach((k, v) -> System.out.println("景点" + k + "的投票人数:" + v));
        }
    }
    
    • 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
    所有学生的选择情况:{关羽=[B, C, D], 张飞=[A, C], 赵云=[A, B, C, D]}
    景点A的投票人数:2
    景点B的投票人数:2
    景点C的投票人数:3
    景点D的投票人数:2
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7



  • 相关阅读:
    代码随想录算法训练营第四十三天| LeetCode1049. 最后一块石头的重量 II、LeetCode494. 目标和、LeetCode474. 一和零
    阿里云新用户滑块验证不过,阿里云滑动验证流程及线上问题排查
    win7 virtualbox使用vagrant下载centos/7
    Unity 公用函数整理【一】
    CSS中如何设置单行或多行内容超出后,显示省略号
    【内网穿透】搭建我的世界Java版服务器,公网远程联机
    Furion api npm web vue混合开发
    为 ASP.NET Core (6.0)服务应用添加ApiKey验证支持
    【mysql体系结构】用户管理
    宜搭,怎么在公式编辑中计算百分比的和?
  • 原文地址:https://blog.csdn.net/yelitoudu/article/details/126689471